1bcea3f96SSteven Rostedt (VMware) // SPDX-License-Identifier: GPL-2.0
2f0868d1eSSteven Rostedt /*
3f0868d1eSSteven Rostedt * trace_output.c
4f0868d1eSSteven Rostedt *
5f0868d1eSSteven Rostedt * Copyright (C) 2008 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
6f0868d1eSSteven Rostedt *
7f0868d1eSSteven Rostedt */
8f0868d1eSSteven Rostedt #include <linux/module.h>
9f0868d1eSSteven Rostedt #include <linux/mutex.h>
10f0868d1eSSteven Rostedt #include <linux/ftrace.h>
117da89495SMasami Hiramatsu #include <linux/kprobes.h>
12e6017571SIngo Molnar #include <linux/sched/clock.h>
136e84f315SIngo Molnar #include <linux/sched/mm.h>
1496e6122cSZheng Yejian #include <linux/idr.h>
15f0868d1eSSteven Rostedt
16f0868d1eSSteven Rostedt #include "trace_output.h"
17f0868d1eSSteven Rostedt
18f0868d1eSSteven Rostedt /* must be a power of 2 */
19f0868d1eSSteven Rostedt #define EVENT_HASHSIZE 128
20f0868d1eSSteven Rostedt
2152f6ad6dSzhangwei(Jovi) DECLARE_RWSEM(trace_event_sem);
22be74b73aSSteven Rostedt
23f0868d1eSSteven Rostedt static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
24f0868d1eSSteven Rostedt
trace_print_bputs_msg_only(struct trace_iterator * iter)2509ae7234SSteven Rostedt (Red Hat) enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter)
2609ae7234SSteven Rostedt (Red Hat) {
2709ae7234SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
2809ae7234SSteven Rostedt (Red Hat) struct trace_entry *entry = iter->ent;
2909ae7234SSteven Rostedt (Red Hat) struct bputs_entry *field;
3009ae7234SSteven Rostedt (Red Hat)
3109ae7234SSteven Rostedt (Red Hat) trace_assign_type(field, entry);
3209ae7234SSteven Rostedt (Red Hat)
3319a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, field->str);
3409ae7234SSteven Rostedt (Red Hat)
3519a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
3609ae7234SSteven Rostedt (Red Hat) }
3709ae7234SSteven Rostedt (Red Hat)
trace_print_bprintk_msg_only(struct trace_iterator * iter)385ef841f6SSteven Rostedt enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
395ef841f6SSteven Rostedt {
405ef841f6SSteven Rostedt struct trace_seq *s = &iter->seq;
415ef841f6SSteven Rostedt struct trace_entry *entry = iter->ent;
425ef841f6SSteven Rostedt struct bprint_entry *field;
435ef841f6SSteven Rostedt
445ef841f6SSteven Rostedt trace_assign_type(field, entry);
455ef841f6SSteven Rostedt
4619a7fe20SSteven Rostedt (Red Hat) trace_seq_bprintf(s, field->fmt, field->buf);
475ef841f6SSteven Rostedt
4819a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
495ef841f6SSteven Rostedt }
505ef841f6SSteven Rostedt
trace_print_printk_msg_only(struct trace_iterator * iter)515ef841f6SSteven Rostedt enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
525ef841f6SSteven Rostedt {
535ef841f6SSteven Rostedt struct trace_seq *s = &iter->seq;
545ef841f6SSteven Rostedt struct trace_entry *entry = iter->ent;
555ef841f6SSteven Rostedt struct print_entry *field;
565ef841f6SSteven Rostedt
575ef841f6SSteven Rostedt trace_assign_type(field, entry);
585ef841f6SSteven Rostedt
5919a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, field->buf);
605ef841f6SSteven Rostedt
6119a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
625ef841f6SSteven Rostedt }
635ef841f6SSteven Rostedt
64be74b73aSSteven Rostedt const char *
trace_print_flags_seq(struct trace_seq * p,const char * delim,unsigned long flags,const struct trace_print_flags * flag_array)65645df987SSteven Rostedt (Red Hat) trace_print_flags_seq(struct trace_seq *p, const char *delim,
66be74b73aSSteven Rostedt unsigned long flags,
67be74b73aSSteven Rostedt const struct trace_print_flags *flag_array)
68be74b73aSSteven Rostedt {
69be74b73aSSteven Rostedt unsigned long mask;
70be74b73aSSteven Rostedt const char *str;
717b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
72e404b321SAndrey Vagin int i, first = 1;
73be74b73aSSteven Rostedt
74be74b73aSSteven Rostedt for (i = 0; flag_array[i].name && flags; i++) {
75be74b73aSSteven Rostedt
76be74b73aSSteven Rostedt mask = flag_array[i].mask;
77be74b73aSSteven Rostedt if ((flags & mask) != mask)
78be74b73aSSteven Rostedt continue;
79be74b73aSSteven Rostedt
80be74b73aSSteven Rostedt str = flag_array[i].name;
81be74b73aSSteven Rostedt flags &= ~mask;
82e404b321SAndrey Vagin if (!first && delim)
83be74b73aSSteven Rostedt trace_seq_puts(p, delim);
84e404b321SAndrey Vagin else
85e404b321SAndrey Vagin first = 0;
86be74b73aSSteven Rostedt trace_seq_puts(p, str);
87be74b73aSSteven Rostedt }
88be74b73aSSteven Rostedt
89be74b73aSSteven Rostedt /* check for left over flags */
90be74b73aSSteven Rostedt if (flags) {
915b349261SSteven Rostedt if (!first && delim)
92be74b73aSSteven Rostedt trace_seq_puts(p, delim);
93be74b73aSSteven Rostedt trace_seq_printf(p, "0x%lx", flags);
94be74b73aSSteven Rostedt }
95be74b73aSSteven Rostedt
96be74b73aSSteven Rostedt trace_seq_putc(p, 0);
97be74b73aSSteven Rostedt
9856d8bd3fSSteven Whitehouse return ret;
99be74b73aSSteven Rostedt }
100645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_flags_seq);
101be74b73aSSteven Rostedt
1020f4fc29dSSteven Rostedt const char *
trace_print_symbols_seq(struct trace_seq * p,unsigned long val,const struct trace_print_flags * symbol_array)103645df987SSteven Rostedt (Red Hat) trace_print_symbols_seq(struct trace_seq *p, unsigned long val,
1040f4fc29dSSteven Rostedt const struct trace_print_flags *symbol_array)
1050f4fc29dSSteven Rostedt {
1060f4fc29dSSteven Rostedt int i;
1077b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
1080f4fc29dSSteven Rostedt
1090f4fc29dSSteven Rostedt for (i = 0; symbol_array[i].name; i++) {
1100f4fc29dSSteven Rostedt
1110f4fc29dSSteven Rostedt if (val != symbol_array[i].mask)
1120f4fc29dSSteven Rostedt continue;
1130f4fc29dSSteven Rostedt
1140f4fc29dSSteven Rostedt trace_seq_puts(p, symbol_array[i].name);
1150f4fc29dSSteven Rostedt break;
1160f4fc29dSSteven Rostedt }
1170f4fc29dSSteven Rostedt
1187b039cb4SSteven Rostedt (Red Hat) if (ret == (const char *)(trace_seq_buffer_ptr(p)))
1190f4fc29dSSteven Rostedt trace_seq_printf(p, "0x%lx", val);
1200f4fc29dSSteven Rostedt
1210f4fc29dSSteven Rostedt trace_seq_putc(p, 0);
1220f4fc29dSSteven Rostedt
12356d8bd3fSSteven Whitehouse return ret;
1240f4fc29dSSteven Rostedt }
125645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_symbols_seq);
1260f4fc29dSSteven Rostedt
1272fc1b6f0Sliubo #if BITS_PER_LONG == 32
1282fc1b6f0Sliubo const char *
trace_print_flags_seq_u64(struct trace_seq * p,const char * delim,unsigned long long flags,const struct trace_print_flags_u64 * flag_array)129d3213e8fSRoss Zwisler trace_print_flags_seq_u64(struct trace_seq *p, const char *delim,
130d3213e8fSRoss Zwisler unsigned long long flags,
131d3213e8fSRoss Zwisler const struct trace_print_flags_u64 *flag_array)
132d3213e8fSRoss Zwisler {
133d3213e8fSRoss Zwisler unsigned long long mask;
134d3213e8fSRoss Zwisler const char *str;
135d3213e8fSRoss Zwisler const char *ret = trace_seq_buffer_ptr(p);
136d3213e8fSRoss Zwisler int i, first = 1;
137d3213e8fSRoss Zwisler
138d3213e8fSRoss Zwisler for (i = 0; flag_array[i].name && flags; i++) {
139d3213e8fSRoss Zwisler
140d3213e8fSRoss Zwisler mask = flag_array[i].mask;
141d3213e8fSRoss Zwisler if ((flags & mask) != mask)
142d3213e8fSRoss Zwisler continue;
143d3213e8fSRoss Zwisler
144d3213e8fSRoss Zwisler str = flag_array[i].name;
145d3213e8fSRoss Zwisler flags &= ~mask;
146d3213e8fSRoss Zwisler if (!first && delim)
147d3213e8fSRoss Zwisler trace_seq_puts(p, delim);
148d3213e8fSRoss Zwisler else
149d3213e8fSRoss Zwisler first = 0;
150d3213e8fSRoss Zwisler trace_seq_puts(p, str);
151d3213e8fSRoss Zwisler }
152d3213e8fSRoss Zwisler
153d3213e8fSRoss Zwisler /* check for left over flags */
154d3213e8fSRoss Zwisler if (flags) {
155d3213e8fSRoss Zwisler if (!first && delim)
156d3213e8fSRoss Zwisler trace_seq_puts(p, delim);
157d3213e8fSRoss Zwisler trace_seq_printf(p, "0x%llx", flags);
158d3213e8fSRoss Zwisler }
159d3213e8fSRoss Zwisler
160d3213e8fSRoss Zwisler trace_seq_putc(p, 0);
161d3213e8fSRoss Zwisler
162d3213e8fSRoss Zwisler return ret;
163d3213e8fSRoss Zwisler }
164d3213e8fSRoss Zwisler EXPORT_SYMBOL(trace_print_flags_seq_u64);
165d3213e8fSRoss Zwisler
166d3213e8fSRoss Zwisler const char *
trace_print_symbols_seq_u64(struct trace_seq * p,unsigned long long val,const struct trace_print_flags_u64 * symbol_array)167645df987SSteven Rostedt (Red Hat) trace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
1682fc1b6f0Sliubo const struct trace_print_flags_u64 *symbol_array)
1692fc1b6f0Sliubo {
1702fc1b6f0Sliubo int i;
1717b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
1722fc1b6f0Sliubo
1732fc1b6f0Sliubo for (i = 0; symbol_array[i].name; i++) {
1742fc1b6f0Sliubo
1752fc1b6f0Sliubo if (val != symbol_array[i].mask)
1762fc1b6f0Sliubo continue;
1772fc1b6f0Sliubo
1782fc1b6f0Sliubo trace_seq_puts(p, symbol_array[i].name);
1792fc1b6f0Sliubo break;
1802fc1b6f0Sliubo }
1812fc1b6f0Sliubo
1827b039cb4SSteven Rostedt (Red Hat) if (ret == (const char *)(trace_seq_buffer_ptr(p)))
1832fc1b6f0Sliubo trace_seq_printf(p, "0x%llx", val);
1842fc1b6f0Sliubo
1852fc1b6f0Sliubo trace_seq_putc(p, 0);
1862fc1b6f0Sliubo
1872fc1b6f0Sliubo return ret;
1882fc1b6f0Sliubo }
189645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_symbols_seq_u64);
1902fc1b6f0Sliubo #endif
1912fc1b6f0Sliubo
1925a2e3995SKei Tokunaga const char *
trace_print_bitmask_seq(struct trace_seq * p,void * bitmask_ptr,unsigned int bitmask_size)193645df987SSteven Rostedt (Red Hat) trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr,
1944449bf92SSteven Rostedt (Red Hat) unsigned int bitmask_size)
1954449bf92SSteven Rostedt (Red Hat) {
1967b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
1974449bf92SSteven Rostedt (Red Hat)
1984449bf92SSteven Rostedt (Red Hat) trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8);
1994449bf92SSteven Rostedt (Red Hat) trace_seq_putc(p, 0);
2004449bf92SSteven Rostedt (Red Hat)
2014449bf92SSteven Rostedt (Red Hat) return ret;
2024449bf92SSteven Rostedt (Red Hat) }
203645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(trace_print_bitmask_seq);
2044449bf92SSteven Rostedt (Red Hat)
2053898fac1SDaniel Borkmann /**
2063898fac1SDaniel Borkmann * trace_print_hex_seq - print buffer as hex sequence
2073898fac1SDaniel Borkmann * @p: trace seq struct to write to
2083898fac1SDaniel Borkmann * @buf: The buffer to print
2093898fac1SDaniel Borkmann * @buf_len: Length of @buf in bytes
2103898fac1SDaniel Borkmann * @concatenate: Print @buf as single hex string or with spacing
2113898fac1SDaniel Borkmann *
2123898fac1SDaniel Borkmann * Prints the passed buffer as a hex sequence either as a whole,
2133898fac1SDaniel Borkmann * single hex string if @concatenate is true or with spacing after
2143898fac1SDaniel Borkmann * each byte in case @concatenate is false.
2153898fac1SDaniel Borkmann */
2164449bf92SSteven Rostedt (Red Hat) const char *
trace_print_hex_seq(struct trace_seq * p,const unsigned char * buf,int buf_len,bool concatenate)2172acae0d5SDaniel Borkmann trace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len,
2183898fac1SDaniel Borkmann bool concatenate)
2195a2e3995SKei Tokunaga {
2205a2e3995SKei Tokunaga int i;
2217b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
222119cdbdbSAndy Shevchenko const char *fmt = concatenate ? "%*phN" : "%*ph";
2235a2e3995SKei Tokunaga
224adace440SKen Lin for (i = 0; i < buf_len; i += 16) {
225adace440SKen Lin if (!concatenate && i != 0)
226adace440SKen Lin trace_seq_putc(p, ' ');
227119cdbdbSAndy Shevchenko trace_seq_printf(p, fmt, min(buf_len - i, 16), &buf[i]);
228adace440SKen Lin }
2295a2e3995SKei Tokunaga trace_seq_putc(p, 0);
2305a2e3995SKei Tokunaga
2315a2e3995SKei Tokunaga return ret;
2325a2e3995SKei Tokunaga }
233645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_hex_seq);
2345a2e3995SKei Tokunaga
2356ea22486SDave Martin const char *
trace_print_array_seq(struct trace_seq * p,const void * buf,int count,size_t el_size)236645df987SSteven Rostedt (Red Hat) trace_print_array_seq(struct trace_seq *p, const void *buf, int count,
2376ea22486SDave Martin size_t el_size)
2386ea22486SDave Martin {
2396ea22486SDave Martin const char *ret = trace_seq_buffer_ptr(p);
2406ea22486SDave Martin const char *prefix = "";
2416ea22486SDave Martin void *ptr = (void *)buf;
242ac01ce14SAlex Bennée size_t buf_len = count * el_size;
2436ea22486SDave Martin
2446ea22486SDave Martin trace_seq_putc(p, '{');
2456ea22486SDave Martin
2466ea22486SDave Martin while (ptr < buf + buf_len) {
2476ea22486SDave Martin switch (el_size) {
2486ea22486SDave Martin case 1:
2496ea22486SDave Martin trace_seq_printf(p, "%s0x%x", prefix,
2506ea22486SDave Martin *(u8 *)ptr);
2516ea22486SDave Martin break;
2526ea22486SDave Martin case 2:
2536ea22486SDave Martin trace_seq_printf(p, "%s0x%x", prefix,
2546ea22486SDave Martin *(u16 *)ptr);
2556ea22486SDave Martin break;
2566ea22486SDave Martin case 4:
2576ea22486SDave Martin trace_seq_printf(p, "%s0x%x", prefix,
2586ea22486SDave Martin *(u32 *)ptr);
2596ea22486SDave Martin break;
2606ea22486SDave Martin case 8:
2616ea22486SDave Martin trace_seq_printf(p, "%s0x%llx", prefix,
2626ea22486SDave Martin *(u64 *)ptr);
2636ea22486SDave Martin break;
2646ea22486SDave Martin default:
2656ea22486SDave Martin trace_seq_printf(p, "BAD SIZE:%zu 0x%x", el_size,
2666ea22486SDave Martin *(u8 *)ptr);
2676ea22486SDave Martin el_size = 1;
2686ea22486SDave Martin }
2696ea22486SDave Martin prefix = ",";
2706ea22486SDave Martin ptr += el_size;
2716ea22486SDave Martin }
2726ea22486SDave Martin
2736ea22486SDave Martin trace_seq_putc(p, '}');
2746ea22486SDave Martin trace_seq_putc(p, 0);
2756ea22486SDave Martin
2766ea22486SDave Martin return ret;
2776ea22486SDave Martin }
278645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_array_seq);
2796ea22486SDave Martin
280ef56e047SPiotr Maziarz const char *
trace_print_hex_dump_seq(struct trace_seq * p,const char * prefix_str,int prefix_type,int rowsize,int groupsize,const void * buf,size_t len,bool ascii)281ef56e047SPiotr Maziarz trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str,
282ef56e047SPiotr Maziarz int prefix_type, int rowsize, int groupsize,
283ef56e047SPiotr Maziarz const void *buf, size_t len, bool ascii)
284ef56e047SPiotr Maziarz {
285ef56e047SPiotr Maziarz const char *ret = trace_seq_buffer_ptr(p);
286ef56e047SPiotr Maziarz
287ef56e047SPiotr Maziarz trace_seq_putc(p, '\n');
288ef56e047SPiotr Maziarz trace_seq_hex_dump(p, prefix_str, prefix_type,
289ef56e047SPiotr Maziarz rowsize, groupsize, buf, len, ascii);
290ef56e047SPiotr Maziarz trace_seq_putc(p, 0);
291ef56e047SPiotr Maziarz return ret;
292ef56e047SPiotr Maziarz }
293ef56e047SPiotr Maziarz EXPORT_SYMBOL(trace_print_hex_dump_seq);
294ef56e047SPiotr Maziarz
trace_raw_output_prep(struct trace_iterator * iter,struct trace_event * trace_event)295892c505aSSteven Rostedt (Red Hat) int trace_raw_output_prep(struct trace_iterator *iter,
296f71130deSLi Zefan struct trace_event *trace_event)
297f71130deSLi Zefan {
2982425bcb9SSteven Rostedt (Red Hat) struct trace_event_call *event;
299f71130deSLi Zefan struct trace_seq *s = &iter->seq;
300f71130deSLi Zefan struct trace_seq *p = &iter->tmp_seq;
301f71130deSLi Zefan struct trace_entry *entry;
302f71130deSLi Zefan
3032425bcb9SSteven Rostedt (Red Hat) event = container_of(trace_event, struct trace_event_call, event);
304f71130deSLi Zefan entry = iter->ent;
305f71130deSLi Zefan
306f71130deSLi Zefan if (entry->type != event->event.type) {
307f71130deSLi Zefan WARN_ON_ONCE(1);
308f71130deSLi Zefan return TRACE_TYPE_UNHANDLED;
309f71130deSLi Zefan }
310f71130deSLi Zefan
311f71130deSLi Zefan trace_seq_init(p);
312687fcc4aSSteven Rostedt (Red Hat) trace_seq_printf(s, "%s: ", trace_event_name(event));
31319a7fe20SSteven Rostedt (Red Hat)
3148e2e095cSSteven Rostedt (Red Hat) return trace_handle_return(s);
315f71130deSLi Zefan }
316892c505aSSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_raw_output_prep);
317f71130deSLi Zefan
trace_event_printf(struct trace_iterator * iter,const char * fmt,...)318efbbdaa2SMasami Hiramatsu void trace_event_printf(struct trace_iterator *iter, const char *fmt, ...)
319efbbdaa2SMasami Hiramatsu {
320*f452f397SSteven Rostedt struct trace_seq *s = &iter->seq;
321efbbdaa2SMasami Hiramatsu va_list ap;
322efbbdaa2SMasami Hiramatsu
323*f452f397SSteven Rostedt if (ignore_event(iter))
324*f452f397SSteven Rostedt return;
325*f452f397SSteven Rostedt
326efbbdaa2SMasami Hiramatsu va_start(ap, fmt);
327*f452f397SSteven Rostedt trace_seq_vprintf(s, trace_event_format(iter, fmt), ap);
328efbbdaa2SMasami Hiramatsu va_end(ap);
329efbbdaa2SMasami Hiramatsu }
330efbbdaa2SMasami Hiramatsu EXPORT_SYMBOL(trace_event_printf);
331efbbdaa2SMasami Hiramatsu
332bfd5a5e8SDavid Howells static __printf(3, 0)
trace_output_raw(struct trace_iterator * iter,char * name,char * fmt,va_list ap)333bfd5a5e8SDavid Howells int trace_output_raw(struct trace_iterator *iter, char *name,
3341d6bae96SSteven Rostedt char *fmt, va_list ap)
3351d6bae96SSteven Rostedt {
3361d6bae96SSteven Rostedt struct trace_seq *s = &iter->seq;
3371d6bae96SSteven Rostedt
33819a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, "%s: ", name);
339efbbdaa2SMasami Hiramatsu trace_seq_vprintf(s, trace_event_format(iter, fmt), ap);
3401d6bae96SSteven Rostedt
34119a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
3421d6bae96SSteven Rostedt }
3431d6bae96SSteven Rostedt
trace_output_call(struct trace_iterator * iter,char * name,char * fmt,...)344892c505aSSteven Rostedt (Red Hat) int trace_output_call(struct trace_iterator *iter, char *name, char *fmt, ...)
3451d6bae96SSteven Rostedt {
3461d6bae96SSteven Rostedt va_list ap;
3471d6bae96SSteven Rostedt int ret;
3481d6bae96SSteven Rostedt
3491d6bae96SSteven Rostedt va_start(ap, fmt);
350892c505aSSteven Rostedt (Red Hat) ret = trace_output_raw(iter, name, fmt, ap);
3511d6bae96SSteven Rostedt va_end(ap);
3521d6bae96SSteven Rostedt
3531d6bae96SSteven Rostedt return ret;
3541d6bae96SSteven Rostedt }
355892c505aSSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(trace_output_call);
3561d6bae96SSteven Rostedt
kretprobed(const char * name,unsigned long addr)3577da89495SMasami Hiramatsu static inline const char *kretprobed(const char *name, unsigned long addr)
358f0868d1eSSteven Rostedt {
3597da89495SMasami Hiramatsu if (is_kretprobe_trampoline(addr))
360f0868d1eSSteven Rostedt return "[unknown/kretprobe'd]";
361f0868d1eSSteven Rostedt return name;
362f0868d1eSSteven Rostedt }
363f0868d1eSSteven Rostedt
364773c1670SSteven Rostedt (VMware) void
trace_seq_print_sym(struct trace_seq * s,unsigned long address,bool offset)365773c1670SSteven Rostedt (VMware) trace_seq_print_sym(struct trace_seq *s, unsigned long address, bool offset)
366f0868d1eSSteven Rostedt {
367feaf1283SSteven Rostedt (VMware) #ifdef CONFIG_KALLSYMS
368bea6957dSRasmus Villemoes char str[KSYM_SYMBOL_LEN];
369f0868d1eSSteven Rostedt const char *name;
370f0868d1eSSteven Rostedt
37159dd974bSRasmus Villemoes if (offset)
372f0868d1eSSteven Rostedt sprint_symbol(str, address);
37359dd974bSRasmus Villemoes else
37459dd974bSRasmus Villemoes kallsyms_lookup(address, NULL, NULL, NULL, str);
3757da89495SMasami Hiramatsu name = kretprobed(str, address);
376f0868d1eSSteven Rostedt
377feaf1283SSteven Rostedt (VMware) if (name && strlen(name)) {
378bea6957dSRasmus Villemoes trace_seq_puts(s, name);
379feaf1283SSteven Rostedt (VMware) return;
380feaf1283SSteven Rostedt (VMware) }
381f0868d1eSSteven Rostedt #endif
382bea6957dSRasmus Villemoes trace_seq_printf(s, "0x%08lx", address);
383f0868d1eSSteven Rostedt }
384f0868d1eSSteven Rostedt
385f0868d1eSSteven Rostedt #ifndef CONFIG_64BIT
386f0868d1eSSteven Rostedt # define IP_FMT "%08lx"
387f0868d1eSSteven Rostedt #else
388f0868d1eSSteven Rostedt # define IP_FMT "%016lx"
389f0868d1eSSteven Rostedt #endif
390f0868d1eSSteven Rostedt
seq_print_user_ip(struct trace_seq * s,struct mm_struct * mm,unsigned long ip,unsigned long sym_flags)391ef92480aSSteven Rostedt (Red Hat) static int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
392f0868d1eSSteven Rostedt unsigned long ip, unsigned long sym_flags)
393f0868d1eSSteven Rostedt {
394f0868d1eSSteven Rostedt struct file *file = NULL;
395f0868d1eSSteven Rostedt unsigned long vmstart = 0;
396f0868d1eSSteven Rostedt int ret = 1;
397f0868d1eSSteven Rostedt
398d184b31cSJohannes Berg if (s->full)
399d184b31cSJohannes Berg return 0;
400d184b31cSJohannes Berg
401f0868d1eSSteven Rostedt if (mm) {
402f0868d1eSSteven Rostedt const struct vm_area_struct *vma;
403f0868d1eSSteven Rostedt
404d8ed45c5SMichel Lespinasse mmap_read_lock(mm);
405f0868d1eSSteven Rostedt vma = find_vma(mm, ip);
406f0868d1eSSteven Rostedt if (vma) {
407f0868d1eSSteven Rostedt file = vma->vm_file;
408f0868d1eSSteven Rostedt vmstart = vma->vm_start;
409f0868d1eSSteven Rostedt }
410f0868d1eSSteven Rostedt if (file) {
411f0868d1eSSteven Rostedt ret = trace_seq_path(s, &file->f_path);
412f0868d1eSSteven Rostedt if (ret)
41319a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, "[+0x%lx]",
414f0868d1eSSteven Rostedt ip - vmstart);
415f0868d1eSSteven Rostedt }
416d8ed45c5SMichel Lespinasse mmap_read_unlock(mm);
417f0868d1eSSteven Rostedt }
418f0868d1eSSteven Rostedt if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
41919a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, " <" IP_FMT ">", ip);
42019a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
421f0868d1eSSteven Rostedt }
422f0868d1eSSteven Rostedt
423f0868d1eSSteven Rostedt int
seq_print_ip_sym(struct trace_seq * s,unsigned long ip,unsigned long sym_flags)424f0868d1eSSteven Rostedt seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
425f0868d1eSSteven Rostedt {
42619a7fe20SSteven Rostedt (Red Hat) if (!ip) {
42719a7fe20SSteven Rostedt (Red Hat) trace_seq_putc(s, '0');
42819a7fe20SSteven Rostedt (Red Hat) goto out;
42919a7fe20SSteven Rostedt (Red Hat) }
430f0868d1eSSteven Rostedt
431773c1670SSteven Rostedt (VMware) trace_seq_print_sym(s, ip, sym_flags & TRACE_ITER_SYM_OFFSET);
432f0868d1eSSteven Rostedt
433f0868d1eSSteven Rostedt if (sym_flags & TRACE_ITER_SYM_ADDR)
43419a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, " <" IP_FMT ">", ip);
43519a7fe20SSteven Rostedt (Red Hat)
43619a7fe20SSteven Rostedt (Red Hat) out:
43719a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
438f0868d1eSSteven Rostedt }
439f0868d1eSSteven Rostedt
440f81c972dSSteven Rostedt /**
441f81c972dSSteven Rostedt * trace_print_lat_fmt - print the irq, preempt and lockdep fields
442f81c972dSSteven Rostedt * @s: trace seq struct to write to
443f81c972dSSteven Rostedt * @entry: The trace entry field from the ring buffer
444f81c972dSSteven Rostedt *
445f81c972dSSteven Rostedt * Prints the generic fields of irqs off, in hard or softirq, preempt
446e6e1e259SSteven Rostedt * count.
447f81c972dSSteven Rostedt */
trace_print_lat_fmt(struct trace_seq * s,struct trace_entry * entry)448f81c972dSSteven Rostedt int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
449c4a8e8beSFrederic Weisbecker {
45010da37a6SDavid Sharp char hardsoft_irq;
45110da37a6SDavid Sharp char need_resched;
45210da37a6SDavid Sharp char irqs_off;
45310da37a6SDavid Sharp int hardirq;
45410da37a6SDavid Sharp int softirq;
455289e7b0fSSebastian Andrzej Siewior int bh_off;
4567e6867bfSPeter Zijlstra int nmi;
457c4a8e8beSFrederic Weisbecker
4587e6867bfSPeter Zijlstra nmi = entry->flags & TRACE_FLAG_NMI;
459c4a8e8beSFrederic Weisbecker hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
460c4a8e8beSFrederic Weisbecker softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
461289e7b0fSSebastian Andrzej Siewior bh_off = entry->flags & TRACE_FLAG_BH_OFF;
462d9793bd8SArnaldo Carvalho de Melo
46310da37a6SDavid Sharp irqs_off =
464289e7b0fSSebastian Andrzej Siewior (entry->flags & TRACE_FLAG_IRQS_OFF && bh_off) ? 'D' :
465d9793bd8SArnaldo Carvalho de Melo (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
466289e7b0fSSebastian Andrzej Siewior bh_off ? 'b' :
46710da37a6SDavid Sharp (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' :
46810da37a6SDavid Sharp '.';
469e5137b50SPeter Zijlstra
470e5137b50SPeter Zijlstra switch (entry->flags & (TRACE_FLAG_NEED_RESCHED |
471e5137b50SPeter Zijlstra TRACE_FLAG_PREEMPT_RESCHED)) {
472e5137b50SPeter Zijlstra case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED:
473e5137b50SPeter Zijlstra need_resched = 'N';
474e5137b50SPeter Zijlstra break;
475e5137b50SPeter Zijlstra case TRACE_FLAG_NEED_RESCHED:
476e5137b50SPeter Zijlstra need_resched = 'n';
477e5137b50SPeter Zijlstra break;
478e5137b50SPeter Zijlstra case TRACE_FLAG_PREEMPT_RESCHED:
479e5137b50SPeter Zijlstra need_resched = 'p';
480e5137b50SPeter Zijlstra break;
481e5137b50SPeter Zijlstra default:
482e5137b50SPeter Zijlstra need_resched = '.';
483e5137b50SPeter Zijlstra break;
484e5137b50SPeter Zijlstra }
485e5137b50SPeter Zijlstra
48610da37a6SDavid Sharp hardsoft_irq =
4877e6867bfSPeter Zijlstra (nmi && hardirq) ? 'Z' :
4887e6867bfSPeter Zijlstra nmi ? 'z' :
489d9793bd8SArnaldo Carvalho de Melo (hardirq && softirq) ? 'H' :
49010da37a6SDavid Sharp hardirq ? 'h' :
49110da37a6SDavid Sharp softirq ? 's' :
49210da37a6SDavid Sharp '.' ;
49310da37a6SDavid Sharp
49419a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, "%c%c%c",
49519a7fe20SSteven Rostedt (Red Hat) irqs_off, need_resched, hardsoft_irq);
496c4a8e8beSFrederic Weisbecker
49754357f0cSThomas Gleixner if (entry->preempt_count & 0xf)
49854357f0cSThomas Gleixner trace_seq_printf(s, "%x", entry->preempt_count & 0xf);
49954357f0cSThomas Gleixner else
50054357f0cSThomas Gleixner trace_seq_putc(s, '.');
50154357f0cSThomas Gleixner
50254357f0cSThomas Gleixner if (entry->preempt_count & 0xf0)
50354357f0cSThomas Gleixner trace_seq_printf(s, "%x", entry->preempt_count >> 4);
504637e7e86SSteven Rostedt else
50519a7fe20SSteven Rostedt (Red Hat) trace_seq_putc(s, '.');
506829b876dSSteven Rostedt
50719a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
508c4a8e8beSFrederic Weisbecker }
509c4a8e8beSFrederic Weisbecker
510f81c972dSSteven Rostedt static int
lat_print_generic(struct trace_seq * s,struct trace_entry * entry,int cpu)511f81c972dSSteven Rostedt lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
512f81c972dSSteven Rostedt {
513f81c972dSSteven Rostedt char comm[TASK_COMM_LEN];
514f81c972dSSteven Rostedt
515f81c972dSSteven Rostedt trace_find_cmdline(entry->pid, comm);
516f81c972dSSteven Rostedt
517795d6379SSebastian Andrzej Siewior trace_seq_printf(s, "%8.8s-%-7d %3d",
51819a7fe20SSteven Rostedt (Red Hat) comm, entry->pid, cpu);
519f81c972dSSteven Rostedt
520f81c972dSSteven Rostedt return trace_print_lat_fmt(s, entry);
521f81c972dSSteven Rostedt }
522f81c972dSSteven Rostedt
5238e1e1df2SByungchul Park #undef MARK
5248e1e1df2SByungchul Park #define MARK(v, s) {.val = v, .sym = s}
5258e1e1df2SByungchul Park /* trace overhead mark */
5268e1e1df2SByungchul Park static const struct trace_mark {
5278e1e1df2SByungchul Park unsigned long long val; /* unit: nsec */
5288e1e1df2SByungchul Park char sym;
5298e1e1df2SByungchul Park } mark[] = {
5308e1e1df2SByungchul Park MARK(1000000000ULL , '$'), /* 1 sec */
531b838e1d9SJungseok Lee MARK(100000000ULL , '@'), /* 100 msec */
532b838e1d9SJungseok Lee MARK(10000000ULL , '*'), /* 10 msec */
5338e1e1df2SByungchul Park MARK(1000000ULL , '#'), /* 1000 usecs */
5348e1e1df2SByungchul Park MARK(100000ULL , '!'), /* 100 usecs */
5358e1e1df2SByungchul Park MARK(10000ULL , '+'), /* 10 usecs */
5368e1e1df2SByungchul Park };
5378e1e1df2SByungchul Park #undef MARK
5388e1e1df2SByungchul Park
trace_find_mark(unsigned long long d)5398e1e1df2SByungchul Park char trace_find_mark(unsigned long long d)
5408e1e1df2SByungchul Park {
5418e1e1df2SByungchul Park int i;
5428e1e1df2SByungchul Park int size = ARRAY_SIZE(mark);
5438e1e1df2SByungchul Park
5448e1e1df2SByungchul Park for (i = 0; i < size; i++) {
545b838e1d9SJungseok Lee if (d > mark[i].val)
5468e1e1df2SByungchul Park break;
5478e1e1df2SByungchul Park }
5488e1e1df2SByungchul Park
5498e1e1df2SByungchul Park return (i == size) ? ' ' : mark[i].sym;
5508e1e1df2SByungchul Park }
551c4a8e8beSFrederic Weisbecker
552d9793bd8SArnaldo Carvalho de Melo static int
lat_print_timestamp(struct trace_iterator * iter,u64 next_ts)5538be0709fSDavid Sharp lat_print_timestamp(struct trace_iterator *iter, u64 next_ts)
554c4a8e8beSFrederic Weisbecker {
555983f938aSSteven Rostedt (Red Hat) struct trace_array *tr = iter->tr;
556983f938aSSteven Rostedt (Red Hat) unsigned long verbose = tr->trace_flags & TRACE_ITER_VERBOSE;
5578be0709fSDavid Sharp unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS;
5581c5eb448SSteven Rostedt (VMware) unsigned long long abs_ts = iter->ts - iter->array_buffer->time_start;
5598be0709fSDavid Sharp unsigned long long rel_ts = next_ts - iter->ts;
5608be0709fSDavid Sharp struct trace_seq *s = &iter->seq;
5618be0709fSDavid Sharp
5628be0709fSDavid Sharp if (in_ns) {
5638be0709fSDavid Sharp abs_ts = ns2usecs(abs_ts);
5648be0709fSDavid Sharp rel_ts = ns2usecs(rel_ts);
5658be0709fSDavid Sharp }
5668be0709fSDavid Sharp
5678be0709fSDavid Sharp if (verbose && in_ns) {
5688be0709fSDavid Sharp unsigned long abs_usec = do_div(abs_ts, USEC_PER_MSEC);
5698be0709fSDavid Sharp unsigned long abs_msec = (unsigned long)abs_ts;
5708be0709fSDavid Sharp unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC);
5718be0709fSDavid Sharp unsigned long rel_msec = (unsigned long)rel_ts;
5728be0709fSDavid Sharp
57319a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(
5748be0709fSDavid Sharp s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ",
5758be0709fSDavid Sharp ns2usecs(iter->ts),
5768be0709fSDavid Sharp abs_msec, abs_usec,
5778be0709fSDavid Sharp rel_msec, rel_usec);
57819a7fe20SSteven Rostedt (Red Hat)
5798be0709fSDavid Sharp } else if (verbose && !in_ns) {
58019a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(
5818be0709fSDavid Sharp s, "[%016llx] %lld (+%lld): ",
5828be0709fSDavid Sharp iter->ts, abs_ts, rel_ts);
58319a7fe20SSteven Rostedt (Red Hat)
5848be0709fSDavid Sharp } else if (!verbose && in_ns) {
58519a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(
5868be0709fSDavid Sharp s, " %4lldus%c: ",
5878be0709fSDavid Sharp abs_ts,
5888e1e1df2SByungchul Park trace_find_mark(rel_ts * NSEC_PER_USEC));
58919a7fe20SSteven Rostedt (Red Hat)
5908be0709fSDavid Sharp } else { /* !verbose && !in_ns */
59119a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, " %4lld: ", abs_ts);
5928be0709fSDavid Sharp }
59319a7fe20SSteven Rostedt (Red Hat)
59419a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
595c4a8e8beSFrederic Weisbecker }
596c4a8e8beSFrederic Weisbecker
trace_print_time(struct trace_seq * s,struct trace_iterator * iter,unsigned long long ts)597eaa7a897SYordan Karadzhov (VMware) static void trace_print_time(struct trace_seq *s, struct trace_iterator *iter,
598eaa7a897SYordan Karadzhov (VMware) unsigned long long ts)
599eaa7a897SYordan Karadzhov (VMware) {
600eaa7a897SYordan Karadzhov (VMware) unsigned long secs, usec_rem;
601eaa7a897SYordan Karadzhov (VMware) unsigned long long t;
602eaa7a897SYordan Karadzhov (VMware)
603eaa7a897SYordan Karadzhov (VMware) if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) {
604eaa7a897SYordan Karadzhov (VMware) t = ns2usecs(ts);
605eaa7a897SYordan Karadzhov (VMware) usec_rem = do_div(t, USEC_PER_SEC);
606eaa7a897SYordan Karadzhov (VMware) secs = (unsigned long)t;
607eaa7a897SYordan Karadzhov (VMware) trace_seq_printf(s, " %5lu.%06lu", secs, usec_rem);
608eaa7a897SYordan Karadzhov (VMware) } else
609eaa7a897SYordan Karadzhov (VMware) trace_seq_printf(s, " %12llu", ts);
610eaa7a897SYordan Karadzhov (VMware) }
611eaa7a897SYordan Karadzhov (VMware)
trace_print_context(struct trace_iterator * iter)612c4a8e8beSFrederic Weisbecker int trace_print_context(struct trace_iterator *iter)
613c4a8e8beSFrederic Weisbecker {
614983f938aSSteven Rostedt (Red Hat) struct trace_array *tr = iter->tr;
615c4a8e8beSFrederic Weisbecker struct trace_seq *s = &iter->seq;
616c4a8e8beSFrederic Weisbecker struct trace_entry *entry = iter->ent;
6174ca53085SSteven Rostedt char comm[TASK_COMM_LEN];
6184ca53085SSteven Rostedt
6194ca53085SSteven Rostedt trace_find_cmdline(entry->pid, comm);
620c4a8e8beSFrederic Weisbecker
621795d6379SSebastian Andrzej Siewior trace_seq_printf(s, "%16s-%-7d ", comm, entry->pid);
62277271ce4SSteven Rostedt
623441dae8fSJoel Fernandes if (tr->trace_flags & TRACE_ITER_RECORD_TGID) {
624441dae8fSJoel Fernandes unsigned int tgid = trace_find_tgid(entry->pid);
625441dae8fSJoel Fernandes
626441dae8fSJoel Fernandes if (!tgid)
627795d6379SSebastian Andrzej Siewior trace_seq_printf(s, "(-------) ");
628441dae8fSJoel Fernandes else
629795d6379SSebastian Andrzej Siewior trace_seq_printf(s, "(%7d) ", tgid);
630441dae8fSJoel Fernandes }
631441dae8fSJoel Fernandes
632f8494fa3SJoel Fernandes (Google) trace_seq_printf(s, "[%03d] ", iter->cpu);
633f8494fa3SJoel Fernandes (Google)
634983f938aSSteven Rostedt (Red Hat) if (tr->trace_flags & TRACE_ITER_IRQ_INFO)
63519a7fe20SSteven Rostedt (Red Hat) trace_print_lat_fmt(s, entry);
63677271ce4SSteven Rostedt
637eaa7a897SYordan Karadzhov (VMware) trace_print_time(s, iter, iter->ts);
638eaa7a897SYordan Karadzhov (VMware) trace_seq_puts(s, ": ");
63919a7fe20SSteven Rostedt (Red Hat)
64019a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
641c4a8e8beSFrederic Weisbecker }
642c4a8e8beSFrederic Weisbecker
trace_print_lat_context(struct trace_iterator * iter)643c4a8e8beSFrederic Weisbecker int trace_print_lat_context(struct trace_iterator *iter)
644c4a8e8beSFrederic Weisbecker {
645ff895103SSteven Rostedt (VMware) struct trace_entry *entry, *next_entry;
646983f938aSSteven Rostedt (Red Hat) struct trace_array *tr = iter->tr;
647c4a8e8beSFrederic Weisbecker struct trace_seq *s = &iter->seq;
648983f938aSSteven Rostedt (Red Hat) unsigned long verbose = (tr->trace_flags & TRACE_ITER_VERBOSE);
649ff895103SSteven Rostedt (VMware) u64 next_ts;
650c4a8e8beSFrederic Weisbecker
651ff895103SSteven Rostedt (VMware) next_entry = trace_find_next_entry(iter, NULL, &next_ts);
652c4a8e8beSFrederic Weisbecker if (!next_entry)
653c4a8e8beSFrederic Weisbecker next_ts = iter->ts;
654c4a8e8beSFrederic Weisbecker
655ff895103SSteven Rostedt (VMware) /* trace_find_next_entry() may change iter->ent */
656ff895103SSteven Rostedt (VMware) entry = iter->ent;
657ff895103SSteven Rostedt (VMware)
658c4a8e8beSFrederic Weisbecker if (verbose) {
6594ca53085SSteven Rostedt char comm[TASK_COMM_LEN];
6604ca53085SSteven Rostedt
6614ca53085SSteven Rostedt trace_find_cmdline(entry->pid, comm);
6624ca53085SSteven Rostedt
66319a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(
664795d6379SSebastian Andrzej Siewior s, "%16s %7d %3d %d %08x %08lx ",
6658be0709fSDavid Sharp comm, entry->pid, iter->cpu, entry->flags,
66654357f0cSThomas Gleixner entry->preempt_count & 0xf, iter->idx);
667c4a8e8beSFrederic Weisbecker } else {
66819a7fe20SSteven Rostedt (Red Hat) lat_print_generic(s, entry, iter->cpu);
669c4a8e8beSFrederic Weisbecker }
670c4a8e8beSFrederic Weisbecker
67119a7fe20SSteven Rostedt (Red Hat) lat_print_timestamp(iter, next_ts);
6728be0709fSDavid Sharp
67319a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
674c4a8e8beSFrederic Weisbecker }
675c4a8e8beSFrederic Weisbecker
676f0868d1eSSteven Rostedt /**
677f0868d1eSSteven Rostedt * ftrace_find_event - find a registered event
678f0868d1eSSteven Rostedt * @type: the type of event to look for
679f0868d1eSSteven Rostedt *
680f0868d1eSSteven Rostedt * Returns an event of type @type otherwise NULL
6814f535968SLai Jiangshan * Called with trace_event_read_lock() held.
682f0868d1eSSteven Rostedt */
ftrace_find_event(int type)683f0868d1eSSteven Rostedt struct trace_event *ftrace_find_event(int type)
684f0868d1eSSteven Rostedt {
685f0868d1eSSteven Rostedt struct trace_event *event;
686f0868d1eSSteven Rostedt unsigned key;
687f0868d1eSSteven Rostedt
688f0868d1eSSteven Rostedt key = type & (EVENT_HASHSIZE - 1);
689f0868d1eSSteven Rostedt
690b67bfe0dSSasha Levin hlist_for_each_entry(event, &event_hash[key], node) {
691f0868d1eSSteven Rostedt if (event->type == type)
692f0868d1eSSteven Rostedt return event;
693f0868d1eSSteven Rostedt }
694f0868d1eSSteven Rostedt
695f0868d1eSSteven Rostedt return NULL;
696f0868d1eSSteven Rostedt }
697f0868d1eSSteven Rostedt
69896e6122cSZheng Yejian static DEFINE_IDA(trace_event_ida);
699060fa5c8SSteven Rostedt
free_trace_event_type(int type)70096e6122cSZheng Yejian static void free_trace_event_type(int type)
701060fa5c8SSteven Rostedt {
70296e6122cSZheng Yejian if (type >= __TRACE_LAST_TYPE)
70396e6122cSZheng Yejian ida_free(&trace_event_ida, type);
704060fa5c8SSteven Rostedt }
705060fa5c8SSteven Rostedt
alloc_trace_event_type(void)70696e6122cSZheng Yejian static int alloc_trace_event_type(void)
70796e6122cSZheng Yejian {
70896e6122cSZheng Yejian int next;
709060fa5c8SSteven Rostedt
71096e6122cSZheng Yejian /* Skip static defined type numbers */
71196e6122cSZheng Yejian next = ida_alloc_range(&trace_event_ida, __TRACE_LAST_TYPE,
71296e6122cSZheng Yejian TRACE_EVENT_TYPE_MAX, GFP_KERNEL);
71396e6122cSZheng Yejian if (next < 0)
714060fa5c8SSteven Rostedt return 0;
715746cf345SWei Yang return next;
716060fa5c8SSteven Rostedt }
717060fa5c8SSteven Rostedt
trace_event_read_lock(void)7184f535968SLai Jiangshan void trace_event_read_lock(void)
7194f535968SLai Jiangshan {
72052f6ad6dSzhangwei(Jovi) down_read(&trace_event_sem);
7214f535968SLai Jiangshan }
7224f535968SLai Jiangshan
trace_event_read_unlock(void)7234f535968SLai Jiangshan void trace_event_read_unlock(void)
7244f535968SLai Jiangshan {
72552f6ad6dSzhangwei(Jovi) up_read(&trace_event_sem);
7264f535968SLai Jiangshan }
7274f535968SLai Jiangshan
728f0868d1eSSteven Rostedt /**
7299023c930SSteven Rostedt (Red Hat) * register_trace_event - register output for an event type
730f0868d1eSSteven Rostedt * @event: the event type to register
731f0868d1eSSteven Rostedt *
732f0868d1eSSteven Rostedt * Event types are stored in a hash and this hash is used to
733f0868d1eSSteven Rostedt * find a way to print an event. If the @event->type is set
734f0868d1eSSteven Rostedt * then it will use that type, otherwise it will assign a
735f0868d1eSSteven Rostedt * type to use.
736f0868d1eSSteven Rostedt *
737f0868d1eSSteven Rostedt * If you assign your own type, please make sure it is added
738f0868d1eSSteven Rostedt * to the trace_type enum in trace.h, to avoid collisions
739f0868d1eSSteven Rostedt * with the dynamic types.
740f0868d1eSSteven Rostedt *
741f0868d1eSSteven Rostedt * Returns the event type number or zero on error.
742f0868d1eSSteven Rostedt */
register_trace_event(struct trace_event * event)7439023c930SSteven Rostedt (Red Hat) int register_trace_event(struct trace_event *event)
744f0868d1eSSteven Rostedt {
745f0868d1eSSteven Rostedt unsigned key;
746f0868d1eSSteven Rostedt int ret = 0;
747f0868d1eSSteven Rostedt
74852f6ad6dSzhangwei(Jovi) down_write(&trace_event_sem);
749f0868d1eSSteven Rostedt
750060fa5c8SSteven Rostedt if (WARN_ON(!event))
75128bea271SPeter Zijlstra goto out;
752060fa5c8SSteven Rostedt
753a9a57763SSteven Rostedt if (WARN_ON(!event->funcs))
754a9a57763SSteven Rostedt goto out;
755a9a57763SSteven Rostedt
756060fa5c8SSteven Rostedt if (!event->type) {
75796e6122cSZheng Yejian event->type = alloc_trace_event_type();
758060fa5c8SSteven Rostedt if (!event->type)
759060fa5c8SSteven Rostedt goto out;
7604ee51101SGuo Zhengkui } else if (WARN(event->type > __TRACE_LAST_TYPE,
7614ee51101SGuo Zhengkui "Need to add type to trace.h")) {
762060fa5c8SSteven Rostedt goto out;
763060fa5c8SSteven Rostedt } else {
764060fa5c8SSteven Rostedt /* Is this event already used */
765f0868d1eSSteven Rostedt if (ftrace_find_event(event->type))
766f0868d1eSSteven Rostedt goto out;
767060fa5c8SSteven Rostedt }
768f0868d1eSSteven Rostedt
769a9a57763SSteven Rostedt if (event->funcs->trace == NULL)
770a9a57763SSteven Rostedt event->funcs->trace = trace_nop_print;
771a9a57763SSteven Rostedt if (event->funcs->raw == NULL)
772a9a57763SSteven Rostedt event->funcs->raw = trace_nop_print;
773a9a57763SSteven Rostedt if (event->funcs->hex == NULL)
774a9a57763SSteven Rostedt event->funcs->hex = trace_nop_print;
775a9a57763SSteven Rostedt if (event->funcs->binary == NULL)
776a9a57763SSteven Rostedt event->funcs->binary = trace_nop_print;
777268ccda0SArnaldo Carvalho de Melo
778f0868d1eSSteven Rostedt key = event->type & (EVENT_HASHSIZE - 1);
779f0868d1eSSteven Rostedt
7804f535968SLai Jiangshan hlist_add_head(&event->node, &event_hash[key]);
781f0868d1eSSteven Rostedt
782f0868d1eSSteven Rostedt ret = event->type;
783f0868d1eSSteven Rostedt out:
78452f6ad6dSzhangwei(Jovi) up_write(&trace_event_sem);
785f0868d1eSSteven Rostedt
786f0868d1eSSteven Rostedt return ret;
787f0868d1eSSteven Rostedt }
7889023c930SSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(register_trace_event);
789f0868d1eSSteven Rostedt
790110bf2b7SSteven Rostedt /*
79152f6ad6dSzhangwei(Jovi) * Used by module code with the trace_event_sem held for write.
792110bf2b7SSteven Rostedt */
__unregister_trace_event(struct trace_event * event)7939023c930SSteven Rostedt (Red Hat) int __unregister_trace_event(struct trace_event *event)
794110bf2b7SSteven Rostedt {
795110bf2b7SSteven Rostedt hlist_del(&event->node);
79696e6122cSZheng Yejian free_trace_event_type(event->type);
797110bf2b7SSteven Rostedt return 0;
798110bf2b7SSteven Rostedt }
799110bf2b7SSteven Rostedt
800f0868d1eSSteven Rostedt /**
8019023c930SSteven Rostedt (Red Hat) * unregister_trace_event - remove a no longer used event
802f0868d1eSSteven Rostedt * @event: the event to remove
803f0868d1eSSteven Rostedt */
unregister_trace_event(struct trace_event * event)8049023c930SSteven Rostedt (Red Hat) int unregister_trace_event(struct trace_event *event)
805f0868d1eSSteven Rostedt {
80652f6ad6dSzhangwei(Jovi) down_write(&trace_event_sem);
8079023c930SSteven Rostedt (Red Hat) __unregister_trace_event(event);
80852f6ad6dSzhangwei(Jovi) up_write(&trace_event_sem);
809f0868d1eSSteven Rostedt
810f0868d1eSSteven Rostedt return 0;
811f0868d1eSSteven Rostedt }
8129023c930SSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(unregister_trace_event);
813f633cef0SSteven Rostedt
814f633cef0SSteven Rostedt /*
815f633cef0SSteven Rostedt * Standard events
816f633cef0SSteven Rostedt */
817f633cef0SSteven Rostedt
print_array(struct trace_iterator * iter,void * pos,struct ftrace_event_field * field)81880a76994SSteven Rostedt (Google) static void print_array(struct trace_iterator *iter, void *pos,
81980a76994SSteven Rostedt (Google) struct ftrace_event_field *field)
82080a76994SSteven Rostedt (Google) {
82180a76994SSteven Rostedt (Google) int offset;
82280a76994SSteven Rostedt (Google) int len;
82380a76994SSteven Rostedt (Google) int i;
82480a76994SSteven Rostedt (Google)
82580a76994SSteven Rostedt (Google) offset = *(int *)pos & 0xffff;
82680a76994SSteven Rostedt (Google) len = *(int *)pos >> 16;
82780a76994SSteven Rostedt (Google)
82880a76994SSteven Rostedt (Google) if (field)
829c7bdb079SBeau Belgrave offset += field->offset + sizeof(int);
83080a76994SSteven Rostedt (Google)
831c7bdb079SBeau Belgrave if (offset + len > iter->ent_size) {
83280a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<OVERFLOW>");
83380a76994SSteven Rostedt (Google) return;
83480a76994SSteven Rostedt (Google) }
83580a76994SSteven Rostedt (Google)
836c7bdb079SBeau Belgrave pos = (void *)iter->ent + offset;
837c7bdb079SBeau Belgrave
83880a76994SSteven Rostedt (Google) for (i = 0; i < len; i++, pos++) {
83980a76994SSteven Rostedt (Google) if (i)
84080a76994SSteven Rostedt (Google) trace_seq_putc(&iter->seq, ',');
84180a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%02x", *(unsigned char *)pos);
84280a76994SSteven Rostedt (Google) }
84380a76994SSteven Rostedt (Google) }
84480a76994SSteven Rostedt (Google)
print_fields(struct trace_iterator * iter,struct trace_event_call * call,struct list_head * head)84580a76994SSteven Rostedt (Google) static void print_fields(struct trace_iterator *iter, struct trace_event_call *call,
84680a76994SSteven Rostedt (Google) struct list_head *head)
84780a76994SSteven Rostedt (Google) {
84880a76994SSteven Rostedt (Google) struct ftrace_event_field *field;
84980a76994SSteven Rostedt (Google) int offset;
85080a76994SSteven Rostedt (Google) int len;
85180a76994SSteven Rostedt (Google) int ret;
85280a76994SSteven Rostedt (Google) void *pos;
85380a76994SSteven Rostedt (Google)
854e70bb54dSsunliming list_for_each_entry_reverse(field, head, link) {
85580a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, " %s=", field->name);
85680a76994SSteven Rostedt (Google) if (field->offset + field->size > iter->ent_size) {
85780a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<OVERFLOW>");
85880a76994SSteven Rostedt (Google) continue;
85980a76994SSteven Rostedt (Google) }
86080a76994SSteven Rostedt (Google) pos = (void *)iter->ent + field->offset;
86180a76994SSteven Rostedt (Google)
86280a76994SSteven Rostedt (Google) switch (field->filter_type) {
86380a76994SSteven Rostedt (Google) case FILTER_COMM:
86480a76994SSteven Rostedt (Google) case FILTER_STATIC_STRING:
86580a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%.*s", field->size, (char *)pos);
86680a76994SSteven Rostedt (Google) break;
86780a76994SSteven Rostedt (Google) case FILTER_RDYN_STRING:
86880a76994SSteven Rostedt (Google) case FILTER_DYN_STRING:
86980a76994SSteven Rostedt (Google) offset = *(int *)pos & 0xffff;
87080a76994SSteven Rostedt (Google) len = *(int *)pos >> 16;
87180a76994SSteven Rostedt (Google)
87280a76994SSteven Rostedt (Google) if (field->filter_type == FILTER_RDYN_STRING)
873c7bdb079SBeau Belgrave offset += field->offset + sizeof(int);
87480a76994SSteven Rostedt (Google)
875c7bdb079SBeau Belgrave if (offset + len > iter->ent_size) {
87680a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<OVERFLOW>");
87780a76994SSteven Rostedt (Google) break;
87880a76994SSteven Rostedt (Google) }
87980a76994SSteven Rostedt (Google) pos = (void *)iter->ent + offset;
88080a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%.*s", len, (char *)pos);
88180a76994SSteven Rostedt (Google) break;
88280a76994SSteven Rostedt (Google) case FILTER_PTR_STRING:
88380a76994SSteven Rostedt (Google) if (!iter->fmt_size)
88480a76994SSteven Rostedt (Google) trace_iter_expand_format(iter);
88580a76994SSteven Rostedt (Google) pos = *(void **)pos;
88680a76994SSteven Rostedt (Google) ret = strncpy_from_kernel_nofault(iter->fmt, pos,
88780a76994SSteven Rostedt (Google) iter->fmt_size);
88880a76994SSteven Rostedt (Google) if (ret < 0)
88980a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "(0x%px)", pos);
89080a76994SSteven Rostedt (Google) else
89180a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "(0x%px:%s)",
89280a76994SSteven Rostedt (Google) pos, iter->fmt);
89380a76994SSteven Rostedt (Google) break;
89480a76994SSteven Rostedt (Google) case FILTER_TRACE_FN:
89580a76994SSteven Rostedt (Google) pos = *(void **)pos;
89680a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%pS", pos);
89780a76994SSteven Rostedt (Google) break;
89880a76994SSteven Rostedt (Google) case FILTER_CPU:
89980a76994SSteven Rostedt (Google) case FILTER_OTHER:
90080a76994SSteven Rostedt (Google) switch (field->size) {
90180a76994SSteven Rostedt (Google) case 1:
90280a76994SSteven Rostedt (Google) if (isprint(*(char *)pos)) {
90380a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "'%c'",
90480a76994SSteven Rostedt (Google) *(unsigned char *)pos);
90580a76994SSteven Rostedt (Google) }
90680a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "(%d)",
90780a76994SSteven Rostedt (Google) *(unsigned char *)pos);
90880a76994SSteven Rostedt (Google) break;
90980a76994SSteven Rostedt (Google) case 2:
91080a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "0x%x (%d)",
91180a76994SSteven Rostedt (Google) *(unsigned short *)pos,
91280a76994SSteven Rostedt (Google) *(unsigned short *)pos);
91380a76994SSteven Rostedt (Google) break;
91480a76994SSteven Rostedt (Google) case 4:
91580a76994SSteven Rostedt (Google) /* dynamic array info is 4 bytes */
91680a76994SSteven Rostedt (Google) if (strstr(field->type, "__data_loc")) {
91780a76994SSteven Rostedt (Google) print_array(iter, pos, NULL);
91880a76994SSteven Rostedt (Google) break;
91980a76994SSteven Rostedt (Google) }
92080a76994SSteven Rostedt (Google)
92180a76994SSteven Rostedt (Google) if (strstr(field->type, "__rel_loc")) {
92280a76994SSteven Rostedt (Google) print_array(iter, pos, field);
92380a76994SSteven Rostedt (Google) break;
92480a76994SSteven Rostedt (Google) }
92580a76994SSteven Rostedt (Google)
92680a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "0x%x (%d)",
92780a76994SSteven Rostedt (Google) *(unsigned int *)pos,
92880a76994SSteven Rostedt (Google) *(unsigned int *)pos);
92980a76994SSteven Rostedt (Google) break;
93080a76994SSteven Rostedt (Google) case 8:
93180a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "0x%llx (%lld)",
93280a76994SSteven Rostedt (Google) *(unsigned long long *)pos,
93380a76994SSteven Rostedt (Google) *(unsigned long long *)pos);
93480a76994SSteven Rostedt (Google) break;
93580a76994SSteven Rostedt (Google) default:
93680a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<INVALID-SIZE>");
93780a76994SSteven Rostedt (Google) break;
93880a76994SSteven Rostedt (Google) }
93980a76994SSteven Rostedt (Google) break;
94080a76994SSteven Rostedt (Google) default:
94180a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<INVALID-TYPE>");
94280a76994SSteven Rostedt (Google) }
94380a76994SSteven Rostedt (Google) }
94480a76994SSteven Rostedt (Google) trace_seq_putc(&iter->seq, '\n');
94580a76994SSteven Rostedt (Google) }
94680a76994SSteven Rostedt (Google)
print_event_fields(struct trace_iterator * iter,struct trace_event * event)94780a76994SSteven Rostedt (Google) enum print_line_t print_event_fields(struct trace_iterator *iter,
94880a76994SSteven Rostedt (Google) struct trace_event *event)
94980a76994SSteven Rostedt (Google) {
95080a76994SSteven Rostedt (Google) struct trace_event_call *call;
95180a76994SSteven Rostedt (Google) struct list_head *head;
95280a76994SSteven Rostedt (Google)
95380a76994SSteven Rostedt (Google) /* ftrace defined events have separate call structures */
95480a76994SSteven Rostedt (Google) if (event->type <= __TRACE_LAST_TYPE) {
95580a76994SSteven Rostedt (Google) bool found = false;
95680a76994SSteven Rostedt (Google)
95780a76994SSteven Rostedt (Google) down_read(&trace_event_sem);
95880a76994SSteven Rostedt (Google) list_for_each_entry(call, &ftrace_events, list) {
95980a76994SSteven Rostedt (Google) if (call->event.type == event->type) {
96080a76994SSteven Rostedt (Google) found = true;
96180a76994SSteven Rostedt (Google) break;
96280a76994SSteven Rostedt (Google) }
96380a76994SSteven Rostedt (Google) /* No need to search all events */
96480a76994SSteven Rostedt (Google) if (call->event.type > __TRACE_LAST_TYPE)
96580a76994SSteven Rostedt (Google) break;
96680a76994SSteven Rostedt (Google) }
96780a76994SSteven Rostedt (Google) up_read(&trace_event_sem);
96880a76994SSteven Rostedt (Google) if (!found) {
96980a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "UNKNOWN TYPE %d\n", event->type);
97080a76994SSteven Rostedt (Google) goto out;
97180a76994SSteven Rostedt (Google) }
97280a76994SSteven Rostedt (Google) } else {
97380a76994SSteven Rostedt (Google) call = container_of(event, struct trace_event_call, event);
97480a76994SSteven Rostedt (Google) }
97580a76994SSteven Rostedt (Google) head = trace_get_fields(call);
97680a76994SSteven Rostedt (Google)
97780a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%s:", trace_event_name(call));
97880a76994SSteven Rostedt (Google)
97980a76994SSteven Rostedt (Google) if (head && !list_empty(head))
98080a76994SSteven Rostedt (Google) print_fields(iter, call, head);
98180a76994SSteven Rostedt (Google) else
98280a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "No fields found\n");
98380a76994SSteven Rostedt (Google)
98480a76994SSteven Rostedt (Google) out:
98580a76994SSteven Rostedt (Google) return trace_handle_return(&iter->seq);
98680a76994SSteven Rostedt (Google) }
98780a76994SSteven Rostedt (Google)
trace_nop_print(struct trace_iterator * iter,int flags,struct trace_event * event)988a9a57763SSteven Rostedt enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags,
989a9a57763SSteven Rostedt struct trace_event *event)
990f633cef0SSteven Rostedt {
99119a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(&iter->seq, "type: %d\n", iter->ent->type);
992ee5e51f5SJiri Olsa
99319a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
994f633cef0SSteven Rostedt }
995f633cef0SSteven Rostedt
print_fn_trace(struct trace_seq * s,unsigned long ip,unsigned long parent_ip,int flags)996e1db6338SSteven Rostedt (VMware) static void print_fn_trace(struct trace_seq *s, unsigned long ip,
997e1db6338SSteven Rostedt (VMware) unsigned long parent_ip, int flags)
998e1db6338SSteven Rostedt (VMware) {
999e1db6338SSteven Rostedt (VMware) seq_print_ip_sym(s, ip, flags);
1000e1db6338SSteven Rostedt (VMware)
1001e1db6338SSteven Rostedt (VMware) if ((flags & TRACE_ITER_PRINT_PARENT) && parent_ip) {
1002e1db6338SSteven Rostedt (VMware) trace_seq_puts(s, " <-");
1003e1db6338SSteven Rostedt (VMware) seq_print_ip_sym(s, parent_ip, flags);
1004e1db6338SSteven Rostedt (VMware) }
1005e1db6338SSteven Rostedt (VMware) }
1006e1db6338SSteven Rostedt (VMware)
1007f633cef0SSteven Rostedt /* TRACE_FN */
trace_fn_trace(struct trace_iterator * iter,int flags,struct trace_event * event)1008a9a57763SSteven Rostedt static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags,
1009a9a57763SSteven Rostedt struct trace_event *event)
1010f633cef0SSteven Rostedt {
1011f633cef0SSteven Rostedt struct ftrace_entry *field;
10122c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1013f633cef0SSteven Rostedt
10142c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1015f633cef0SSteven Rostedt
1016e1db6338SSteven Rostedt (VMware) print_fn_trace(s, field->ip, field->parent_ip, flags);
101719a7fe20SSteven Rostedt (Red Hat) trace_seq_putc(s, '\n');
1018f633cef0SSteven Rostedt
101919a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1020f633cef0SSteven Rostedt }
1021f633cef0SSteven Rostedt
trace_fn_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1022a9a57763SSteven Rostedt static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags,
1023a9a57763SSteven Rostedt struct trace_event *event)
1024f633cef0SSteven Rostedt {
1025f633cef0SSteven Rostedt struct ftrace_entry *field;
1026f633cef0SSteven Rostedt
10272c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1028f633cef0SSteven Rostedt
102919a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(&iter->seq, "%lx %lx\n",
1030f633cef0SSteven Rostedt field->ip,
103119a7fe20SSteven Rostedt (Red Hat) field->parent_ip);
1032f633cef0SSteven Rostedt
103319a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
1034f633cef0SSteven Rostedt }
1035f633cef0SSteven Rostedt
trace_fn_hex(struct trace_iterator * iter,int flags,struct trace_event * event)1036a9a57763SSteven Rostedt static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags,
1037a9a57763SSteven Rostedt struct trace_event *event)
1038f633cef0SSteven Rostedt {
1039f633cef0SSteven Rostedt struct ftrace_entry *field;
10402c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1041f633cef0SSteven Rostedt
10422c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1043f633cef0SSteven Rostedt
104419a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->ip);
104519a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->parent_ip);
1046f633cef0SSteven Rostedt
104719a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1048f633cef0SSteven Rostedt }
1049f633cef0SSteven Rostedt
trace_fn_bin(struct trace_iterator * iter,int flags,struct trace_event * event)1050a9a57763SSteven Rostedt static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags,
1051a9a57763SSteven Rostedt struct trace_event *event)
1052f633cef0SSteven Rostedt {
1053f633cef0SSteven Rostedt struct ftrace_entry *field;
10542c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1055f633cef0SSteven Rostedt
10562c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1057f633cef0SSteven Rostedt
105819a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->ip);
105919a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->parent_ip);
1060f633cef0SSteven Rostedt
106119a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1062f633cef0SSteven Rostedt }
1063f633cef0SSteven Rostedt
1064a9a57763SSteven Rostedt static struct trace_event_functions trace_fn_funcs = {
1065f633cef0SSteven Rostedt .trace = trace_fn_trace,
1066f633cef0SSteven Rostedt .raw = trace_fn_raw,
1067f633cef0SSteven Rostedt .hex = trace_fn_hex,
1068f633cef0SSteven Rostedt .binary = trace_fn_bin,
1069f633cef0SSteven Rostedt };
1070f633cef0SSteven Rostedt
1071a9a57763SSteven Rostedt static struct trace_event trace_fn_event = {
1072a9a57763SSteven Rostedt .type = TRACE_FN,
1073a9a57763SSteven Rostedt .funcs = &trace_fn_funcs,
1074a9a57763SSteven Rostedt };
1075a9a57763SSteven Rostedt
1076f633cef0SSteven Rostedt /* TRACE_CTX an TRACE_WAKE */
trace_ctxwake_print(struct trace_iterator * iter,char * delim)1077ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
1078ae7462b4SArnaldo Carvalho de Melo char *delim)
1079f633cef0SSteven Rostedt {
1080f633cef0SSteven Rostedt struct ctx_switch_entry *field;
10814ca53085SSteven Rostedt char comm[TASK_COMM_LEN];
1082f633cef0SSteven Rostedt int S, T;
1083f633cef0SSteven Rostedt
10844ca53085SSteven Rostedt
10852c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1086f633cef0SSteven Rostedt
10871d48b080SPeter Zijlstra T = task_index_to_char(field->next_state);
10881d48b080SPeter Zijlstra S = task_index_to_char(field->prev_state);
10894ca53085SSteven Rostedt trace_find_cmdline(field->next_pid, comm);
109019a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(&iter->seq,
1091795d6379SSebastian Andrzej Siewior " %7d:%3d:%c %s [%03d] %7d:%3d:%c %s\n",
1092f633cef0SSteven Rostedt field->prev_pid,
1093f633cef0SSteven Rostedt field->prev_prio,
1094f633cef0SSteven Rostedt S, delim,
1095f633cef0SSteven Rostedt field->next_cpu,
1096f633cef0SSteven Rostedt field->next_pid,
1097f633cef0SSteven Rostedt field->next_prio,
109819a7fe20SSteven Rostedt (Red Hat) T, comm);
1099f633cef0SSteven Rostedt
110019a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
1101f633cef0SSteven Rostedt }
1102f633cef0SSteven Rostedt
trace_ctx_print(struct trace_iterator * iter,int flags,struct trace_event * event)1103a9a57763SSteven Rostedt static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags,
1104a9a57763SSteven Rostedt struct trace_event *event)
1105f633cef0SSteven Rostedt {
11062c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_print(iter, "==>");
1107f633cef0SSteven Rostedt }
1108f633cef0SSteven Rostedt
trace_wake_print(struct trace_iterator * iter,int flags,struct trace_event * event)1109ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_wake_print(struct trace_iterator *iter,
1110a9a57763SSteven Rostedt int flags, struct trace_event *event)
1111f633cef0SSteven Rostedt {
11122c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_print(iter, " +");
1113f633cef0SSteven Rostedt }
1114f633cef0SSteven Rostedt
trace_ctxwake_raw(struct trace_iterator * iter,char S)11152c9b238eSArnaldo Carvalho de Melo static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
1116f633cef0SSteven Rostedt {
1117f633cef0SSteven Rostedt struct ctx_switch_entry *field;
1118f633cef0SSteven Rostedt int T;
1119f633cef0SSteven Rostedt
11202c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1121f633cef0SSteven Rostedt
1122f633cef0SSteven Rostedt if (!S)
11231d48b080SPeter Zijlstra S = task_index_to_char(field->prev_state);
11241d48b080SPeter Zijlstra T = task_index_to_char(field->next_state);
112519a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
1126f633cef0SSteven Rostedt field->prev_pid,
1127f633cef0SSteven Rostedt field->prev_prio,
1128f633cef0SSteven Rostedt S,
1129f633cef0SSteven Rostedt field->next_cpu,
1130f633cef0SSteven Rostedt field->next_pid,
1131f633cef0SSteven Rostedt field->next_prio,
113219a7fe20SSteven Rostedt (Red Hat) T);
1133f633cef0SSteven Rostedt
113419a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
1135f633cef0SSteven Rostedt }
1136f633cef0SSteven Rostedt
trace_ctx_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1137a9a57763SSteven Rostedt static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags,
1138a9a57763SSteven Rostedt struct trace_event *event)
1139f633cef0SSteven Rostedt {
11402c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_raw(iter, 0);
1141f633cef0SSteven Rostedt }
1142f633cef0SSteven Rostedt
trace_wake_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1143a9a57763SSteven Rostedt static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags,
1144a9a57763SSteven Rostedt struct trace_event *event)
1145f633cef0SSteven Rostedt {
11462c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_raw(iter, '+');
1147f633cef0SSteven Rostedt }
1148f633cef0SSteven Rostedt
1149f633cef0SSteven Rostedt
trace_ctxwake_hex(struct trace_iterator * iter,char S)11502c9b238eSArnaldo Carvalho de Melo static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
1151f633cef0SSteven Rostedt {
1152f633cef0SSteven Rostedt struct ctx_switch_entry *field;
11532c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1154f633cef0SSteven Rostedt int T;
1155f633cef0SSteven Rostedt
11562c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1157f633cef0SSteven Rostedt
1158f633cef0SSteven Rostedt if (!S)
11591d48b080SPeter Zijlstra S = task_index_to_char(field->prev_state);
11601d48b080SPeter Zijlstra T = task_index_to_char(field->next_state);
1161f633cef0SSteven Rostedt
116219a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->prev_pid);
116319a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->prev_prio);
116419a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, S);
116519a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->next_cpu);
116619a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->next_pid);
116719a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->next_prio);
116819a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, T);
1169f633cef0SSteven Rostedt
117019a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1171f633cef0SSteven Rostedt }
1172f633cef0SSteven Rostedt
trace_ctx_hex(struct trace_iterator * iter,int flags,struct trace_event * event)1173a9a57763SSteven Rostedt static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags,
1174a9a57763SSteven Rostedt struct trace_event *event)
1175f633cef0SSteven Rostedt {
11762c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_hex(iter, 0);
1177f633cef0SSteven Rostedt }
1178f633cef0SSteven Rostedt
trace_wake_hex(struct trace_iterator * iter,int flags,struct trace_event * event)1179a9a57763SSteven Rostedt static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags,
1180a9a57763SSteven Rostedt struct trace_event *event)
1181f633cef0SSteven Rostedt {
11822c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_hex(iter, '+');
1183f633cef0SSteven Rostedt }
1184f633cef0SSteven Rostedt
trace_ctxwake_bin(struct trace_iterator * iter,int flags,struct trace_event * event)1185ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
1186a9a57763SSteven Rostedt int flags, struct trace_event *event)
1187f633cef0SSteven Rostedt {
1188f633cef0SSteven Rostedt struct ctx_switch_entry *field;
11892c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1190f633cef0SSteven Rostedt
11912c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1192f633cef0SSteven Rostedt
119319a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->prev_pid);
119419a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->prev_prio);
119519a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->prev_state);
119619a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->next_cpu);
119719a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->next_pid);
119819a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->next_prio);
119919a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->next_state);
1200f633cef0SSteven Rostedt
120119a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1202f633cef0SSteven Rostedt }
1203f633cef0SSteven Rostedt
1204a9a57763SSteven Rostedt static struct trace_event_functions trace_ctx_funcs = {
1205f633cef0SSteven Rostedt .trace = trace_ctx_print,
1206f633cef0SSteven Rostedt .raw = trace_ctx_raw,
1207f633cef0SSteven Rostedt .hex = trace_ctx_hex,
1208f633cef0SSteven Rostedt .binary = trace_ctxwake_bin,
1209f633cef0SSteven Rostedt };
1210f633cef0SSteven Rostedt
1211a9a57763SSteven Rostedt static struct trace_event trace_ctx_event = {
1212a9a57763SSteven Rostedt .type = TRACE_CTX,
1213a9a57763SSteven Rostedt .funcs = &trace_ctx_funcs,
1214a9a57763SSteven Rostedt };
1215a9a57763SSteven Rostedt
1216a9a57763SSteven Rostedt static struct trace_event_functions trace_wake_funcs = {
1217f633cef0SSteven Rostedt .trace = trace_wake_print,
1218f633cef0SSteven Rostedt .raw = trace_wake_raw,
1219f633cef0SSteven Rostedt .hex = trace_wake_hex,
1220f633cef0SSteven Rostedt .binary = trace_ctxwake_bin,
1221f633cef0SSteven Rostedt };
1222f633cef0SSteven Rostedt
1223a9a57763SSteven Rostedt static struct trace_event trace_wake_event = {
1224a9a57763SSteven Rostedt .type = TRACE_WAKE,
1225a9a57763SSteven Rostedt .funcs = &trace_wake_funcs,
1226a9a57763SSteven Rostedt };
1227a9a57763SSteven Rostedt
1228f633cef0SSteven Rostedt /* TRACE_STACK */
1229f633cef0SSteven Rostedt
trace_stack_print(struct trace_iterator * iter,int flags,struct trace_event * event)1230ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_stack_print(struct trace_iterator *iter,
1231a9a57763SSteven Rostedt int flags, struct trace_event *event)
1232f633cef0SSteven Rostedt {
1233f633cef0SSteven Rostedt struct stack_entry *field;
12342c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
12354a9bd3f1SSteven Rostedt unsigned long *p;
12364a9bd3f1SSteven Rostedt unsigned long *end;
1237f633cef0SSteven Rostedt
12382c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
12394a9bd3f1SSteven Rostedt end = (unsigned long *)((long)iter->ent + iter->ent_size);
1240f633cef0SSteven Rostedt
124119a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, "<stack trace>\n");
12424a9bd3f1SSteven Rostedt
1243becf33f6SEiichi Tsukata for (p = field->caller; p && p < end && *p != ULONG_MAX; p++) {
1244f633cef0SSteven Rostedt
124519a7fe20SSteven Rostedt (Red Hat) if (trace_seq_has_overflowed(s))
124619a7fe20SSteven Rostedt (Red Hat) break;
124719a7fe20SSteven Rostedt (Red Hat)
124819a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, " => ");
124919a7fe20SSteven Rostedt (Red Hat) seq_print_ip_sym(s, *p, flags);
125019a7fe20SSteven Rostedt (Red Hat) trace_seq_putc(s, '\n');
1251f633cef0SSteven Rostedt }
1252f633cef0SSteven Rostedt
125319a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1254f633cef0SSteven Rostedt }
1255f633cef0SSteven Rostedt
1256a9a57763SSteven Rostedt static struct trace_event_functions trace_stack_funcs = {
1257f633cef0SSteven Rostedt .trace = trace_stack_print,
1258f633cef0SSteven Rostedt };
1259f633cef0SSteven Rostedt
1260a9a57763SSteven Rostedt static struct trace_event trace_stack_event = {
1261a9a57763SSteven Rostedt .type = TRACE_STACK,
1262a9a57763SSteven Rostedt .funcs = &trace_stack_funcs,
1263a9a57763SSteven Rostedt };
1264a9a57763SSteven Rostedt
1265f633cef0SSteven Rostedt /* TRACE_USER_STACK */
trace_user_stack_print(struct trace_iterator * iter,int flags,struct trace_event * event)1266ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
1267a9a57763SSteven Rostedt int flags, struct trace_event *event)
1268f633cef0SSteven Rostedt {
1269983f938aSSteven Rostedt (Red Hat) struct trace_array *tr = iter->tr;
1270f633cef0SSteven Rostedt struct userstack_entry *field;
12712c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
12726b1032d5SSteven Rostedt (Red Hat) struct mm_struct *mm = NULL;
12736b1032d5SSteven Rostedt (Red Hat) unsigned int i;
1274f633cef0SSteven Rostedt
12752c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1276f633cef0SSteven Rostedt
127719a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, "<user stack trace>\n");
12786b1032d5SSteven Rostedt (Red Hat)
1279983f938aSSteven Rostedt (Red Hat) if (tr->trace_flags & TRACE_ITER_SYM_USEROBJ) {
12806b1032d5SSteven Rostedt (Red Hat) struct task_struct *task;
12816b1032d5SSteven Rostedt (Red Hat) /*
12826b1032d5SSteven Rostedt (Red Hat) * we do the lookup on the thread group leader,
12836b1032d5SSteven Rostedt (Red Hat) * since individual threads might have already quit!
12846b1032d5SSteven Rostedt (Red Hat) */
12856b1032d5SSteven Rostedt (Red Hat) rcu_read_lock();
12866b1032d5SSteven Rostedt (Red Hat) task = find_task_by_vpid(field->tgid);
12876b1032d5SSteven Rostedt (Red Hat) if (task)
12886b1032d5SSteven Rostedt (Red Hat) mm = get_task_mm(task);
12896b1032d5SSteven Rostedt (Red Hat) rcu_read_unlock();
12906b1032d5SSteven Rostedt (Red Hat) }
12916b1032d5SSteven Rostedt (Red Hat)
12926b1032d5SSteven Rostedt (Red Hat) for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
12936b1032d5SSteven Rostedt (Red Hat) unsigned long ip = field->caller[i];
12946b1032d5SSteven Rostedt (Red Hat)
12956d54ceb5SEiichi Tsukata if (!ip || trace_seq_has_overflowed(s))
12966b1032d5SSteven Rostedt (Red Hat) break;
12976b1032d5SSteven Rostedt (Red Hat)
12986b1032d5SSteven Rostedt (Red Hat) trace_seq_puts(s, " => ");
12996b1032d5SSteven Rostedt (Red Hat) seq_print_user_ip(s, mm, ip, flags);
13006b1032d5SSteven Rostedt (Red Hat) trace_seq_putc(s, '\n');
13016b1032d5SSteven Rostedt (Red Hat) }
13026b1032d5SSteven Rostedt (Red Hat)
13036b1032d5SSteven Rostedt (Red Hat) if (mm)
13046b1032d5SSteven Rostedt (Red Hat) mmput(mm);
1305f633cef0SSteven Rostedt
130619a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1307f633cef0SSteven Rostedt }
1308f633cef0SSteven Rostedt
1309a9a57763SSteven Rostedt static struct trace_event_functions trace_user_stack_funcs = {
1310f633cef0SSteven Rostedt .trace = trace_user_stack_print,
1311f633cef0SSteven Rostedt };
1312f633cef0SSteven Rostedt
1313a9a57763SSteven Rostedt static struct trace_event trace_user_stack_event = {
1314a9a57763SSteven Rostedt .type = TRACE_USER_STACK,
1315a9a57763SSteven Rostedt .funcs = &trace_user_stack_funcs,
1316a9a57763SSteven Rostedt };
1317a9a57763SSteven Rostedt
1318e7c15cd8SSteven Rostedt (Red Hat) /* TRACE_HWLAT */
1319e7c15cd8SSteven Rostedt (Red Hat) static enum print_line_t
trace_hwlat_print(struct trace_iterator * iter,int flags,struct trace_event * event)1320e7c15cd8SSteven Rostedt (Red Hat) trace_hwlat_print(struct trace_iterator *iter, int flags,
1321e7c15cd8SSteven Rostedt (Red Hat) struct trace_event *event)
1322e7c15cd8SSteven Rostedt (Red Hat) {
1323e7c15cd8SSteven Rostedt (Red Hat) struct trace_entry *entry = iter->ent;
1324e7c15cd8SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
1325e7c15cd8SSteven Rostedt (Red Hat) struct hwlat_entry *field;
1326e7c15cd8SSteven Rostedt (Red Hat)
1327e7c15cd8SSteven Rostedt (Red Hat) trace_assign_type(field, entry);
1328e7c15cd8SSteven Rostedt (Red Hat)
1329b396bfdeSSteven Rostedt (VMware) trace_seq_printf(s, "#%-5u inner/outer(us): %4llu/%-5llu ts:%lld.%09ld count:%d",
1330e7c15cd8SSteven Rostedt (Red Hat) field->seqnum,
1331e7c15cd8SSteven Rostedt (Red Hat) field->duration,
1332e7c15cd8SSteven Rostedt (Red Hat) field->outer_duration,
133351aad0aeSDeepa Dinamani (long long)field->timestamp.tv_sec,
1334b396bfdeSSteven Rostedt (VMware) field->timestamp.tv_nsec, field->count);
1335e7c15cd8SSteven Rostedt (Red Hat)
13367b2c8625SSteven Rostedt (Red Hat) if (field->nmi_count) {
13377b2c8625SSteven Rostedt (Red Hat) /*
13387b2c8625SSteven Rostedt (Red Hat) * The generic sched_clock() is not NMI safe, thus
13397b2c8625SSteven Rostedt (Red Hat) * we only record the count and not the time.
13407b2c8625SSteven Rostedt (Red Hat) */
13417b2c8625SSteven Rostedt (Red Hat) if (!IS_ENABLED(CONFIG_GENERIC_SCHED_CLOCK))
13427b2c8625SSteven Rostedt (Red Hat) trace_seq_printf(s, " nmi-total:%llu",
13437b2c8625SSteven Rostedt (Red Hat) field->nmi_total_ts);
13447b2c8625SSteven Rostedt (Red Hat) trace_seq_printf(s, " nmi-count:%u",
13457b2c8625SSteven Rostedt (Red Hat) field->nmi_count);
13467b2c8625SSteven Rostedt (Red Hat) }
13477b2c8625SSteven Rostedt (Red Hat)
13487b2c8625SSteven Rostedt (Red Hat) trace_seq_putc(s, '\n');
13497b2c8625SSteven Rostedt (Red Hat)
1350e7c15cd8SSteven Rostedt (Red Hat) return trace_handle_return(s);
1351e7c15cd8SSteven Rostedt (Red Hat) }
1352e7c15cd8SSteven Rostedt (Red Hat)
1353e7c15cd8SSteven Rostedt (Red Hat) static enum print_line_t
trace_hwlat_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1354e7c15cd8SSteven Rostedt (Red Hat) trace_hwlat_raw(struct trace_iterator *iter, int flags,
1355e7c15cd8SSteven Rostedt (Red Hat) struct trace_event *event)
1356e7c15cd8SSteven Rostedt (Red Hat) {
1357e7c15cd8SSteven Rostedt (Red Hat) struct hwlat_entry *field;
1358e7c15cd8SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
1359e7c15cd8SSteven Rostedt (Red Hat)
1360e7c15cd8SSteven Rostedt (Red Hat) trace_assign_type(field, iter->ent);
1361e7c15cd8SSteven Rostedt (Red Hat)
136251aad0aeSDeepa Dinamani trace_seq_printf(s, "%llu %lld %lld %09ld %u\n",
1363e7c15cd8SSteven Rostedt (Red Hat) field->duration,
1364e7c15cd8SSteven Rostedt (Red Hat) field->outer_duration,
136551aad0aeSDeepa Dinamani (long long)field->timestamp.tv_sec,
1366e7c15cd8SSteven Rostedt (Red Hat) field->timestamp.tv_nsec,
1367e7c15cd8SSteven Rostedt (Red Hat) field->seqnum);
1368e7c15cd8SSteven Rostedt (Red Hat)
1369e7c15cd8SSteven Rostedt (Red Hat) return trace_handle_return(s);
1370e7c15cd8SSteven Rostedt (Red Hat) }
1371e7c15cd8SSteven Rostedt (Red Hat)
1372e7c15cd8SSteven Rostedt (Red Hat) static struct trace_event_functions trace_hwlat_funcs = {
1373e7c15cd8SSteven Rostedt (Red Hat) .trace = trace_hwlat_print,
1374e7c15cd8SSteven Rostedt (Red Hat) .raw = trace_hwlat_raw,
1375e7c15cd8SSteven Rostedt (Red Hat) };
1376e7c15cd8SSteven Rostedt (Red Hat)
1377e7c15cd8SSteven Rostedt (Red Hat) static struct trace_event trace_hwlat_event = {
1378e7c15cd8SSteven Rostedt (Red Hat) .type = TRACE_HWLAT,
1379e7c15cd8SSteven Rostedt (Red Hat) .funcs = &trace_hwlat_funcs,
1380e7c15cd8SSteven Rostedt (Red Hat) };
1381e7c15cd8SSteven Rostedt (Red Hat)
1382bce29ac9SDaniel Bristot de Oliveira /* TRACE_OSNOISE */
1383bce29ac9SDaniel Bristot de Oliveira static enum print_line_t
trace_osnoise_print(struct trace_iterator * iter,int flags,struct trace_event * event)1384bce29ac9SDaniel Bristot de Oliveira trace_osnoise_print(struct trace_iterator *iter, int flags,
1385bce29ac9SDaniel Bristot de Oliveira struct trace_event *event)
1386bce29ac9SDaniel Bristot de Oliveira {
1387bce29ac9SDaniel Bristot de Oliveira struct trace_entry *entry = iter->ent;
1388bce29ac9SDaniel Bristot de Oliveira struct trace_seq *s = &iter->seq;
1389bce29ac9SDaniel Bristot de Oliveira struct osnoise_entry *field;
1390bce29ac9SDaniel Bristot de Oliveira u64 ratio, ratio_dec;
1391bce29ac9SDaniel Bristot de Oliveira u64 net_runtime;
1392bce29ac9SDaniel Bristot de Oliveira
1393bce29ac9SDaniel Bristot de Oliveira trace_assign_type(field, entry);
1394bce29ac9SDaniel Bristot de Oliveira
1395bce29ac9SDaniel Bristot de Oliveira /*
1396bce29ac9SDaniel Bristot de Oliveira * compute the available % of cpu time.
1397bce29ac9SDaniel Bristot de Oliveira */
1398bce29ac9SDaniel Bristot de Oliveira net_runtime = field->runtime - field->noise;
1399bce29ac9SDaniel Bristot de Oliveira ratio = net_runtime * 10000000;
1400bce29ac9SDaniel Bristot de Oliveira do_div(ratio, field->runtime);
1401bce29ac9SDaniel Bristot de Oliveira ratio_dec = do_div(ratio, 100000);
1402bce29ac9SDaniel Bristot de Oliveira
1403bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, "%llu %10llu %3llu.%05llu %7llu",
1404bce29ac9SDaniel Bristot de Oliveira field->runtime,
1405bce29ac9SDaniel Bristot de Oliveira field->noise,
1406bce29ac9SDaniel Bristot de Oliveira ratio, ratio_dec,
1407bce29ac9SDaniel Bristot de Oliveira field->max_sample);
1408bce29ac9SDaniel Bristot de Oliveira
1409bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->hw_count);
1410bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->nmi_count);
1411bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->irq_count);
1412bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->softirq_count);
1413bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->thread_count);
1414bce29ac9SDaniel Bristot de Oliveira
1415bce29ac9SDaniel Bristot de Oliveira trace_seq_putc(s, '\n');
1416bce29ac9SDaniel Bristot de Oliveira
1417bce29ac9SDaniel Bristot de Oliveira return trace_handle_return(s);
1418bce29ac9SDaniel Bristot de Oliveira }
1419bce29ac9SDaniel Bristot de Oliveira
1420bce29ac9SDaniel Bristot de Oliveira static enum print_line_t
trace_osnoise_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1421bce29ac9SDaniel Bristot de Oliveira trace_osnoise_raw(struct trace_iterator *iter, int flags,
1422bce29ac9SDaniel Bristot de Oliveira struct trace_event *event)
1423bce29ac9SDaniel Bristot de Oliveira {
1424bce29ac9SDaniel Bristot de Oliveira struct osnoise_entry *field;
1425bce29ac9SDaniel Bristot de Oliveira struct trace_seq *s = &iter->seq;
1426bce29ac9SDaniel Bristot de Oliveira
1427bce29ac9SDaniel Bristot de Oliveira trace_assign_type(field, iter->ent);
1428bce29ac9SDaniel Bristot de Oliveira
1429bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, "%lld %llu %llu %u %u %u %u %u\n",
1430bce29ac9SDaniel Bristot de Oliveira field->runtime,
1431bce29ac9SDaniel Bristot de Oliveira field->noise,
1432bce29ac9SDaniel Bristot de Oliveira field->max_sample,
1433bce29ac9SDaniel Bristot de Oliveira field->hw_count,
1434bce29ac9SDaniel Bristot de Oliveira field->nmi_count,
1435bce29ac9SDaniel Bristot de Oliveira field->irq_count,
1436bce29ac9SDaniel Bristot de Oliveira field->softirq_count,
1437bce29ac9SDaniel Bristot de Oliveira field->thread_count);
1438bce29ac9SDaniel Bristot de Oliveira
1439bce29ac9SDaniel Bristot de Oliveira return trace_handle_return(s);
1440bce29ac9SDaniel Bristot de Oliveira }
1441bce29ac9SDaniel Bristot de Oliveira
1442bce29ac9SDaniel Bristot de Oliveira static struct trace_event_functions trace_osnoise_funcs = {
1443bce29ac9SDaniel Bristot de Oliveira .trace = trace_osnoise_print,
1444bce29ac9SDaniel Bristot de Oliveira .raw = trace_osnoise_raw,
1445bce29ac9SDaniel Bristot de Oliveira };
1446bce29ac9SDaniel Bristot de Oliveira
1447bce29ac9SDaniel Bristot de Oliveira static struct trace_event trace_osnoise_event = {
1448bce29ac9SDaniel Bristot de Oliveira .type = TRACE_OSNOISE,
1449bce29ac9SDaniel Bristot de Oliveira .funcs = &trace_osnoise_funcs,
1450bce29ac9SDaniel Bristot de Oliveira };
1451bce29ac9SDaniel Bristot de Oliveira
1452a955d7eaSDaniel Bristot de Oliveira /* TRACE_TIMERLAT */
1453e88ed227SDaniel Bristot de Oliveira
1454e88ed227SDaniel Bristot de Oliveira static char *timerlat_lat_context[] = {"irq", "thread", "user-ret"};
1455a955d7eaSDaniel Bristot de Oliveira static enum print_line_t
trace_timerlat_print(struct trace_iterator * iter,int flags,struct trace_event * event)1456a955d7eaSDaniel Bristot de Oliveira trace_timerlat_print(struct trace_iterator *iter, int flags,
1457a955d7eaSDaniel Bristot de Oliveira struct trace_event *event)
1458a955d7eaSDaniel Bristot de Oliveira {
1459a955d7eaSDaniel Bristot de Oliveira struct trace_entry *entry = iter->ent;
1460a955d7eaSDaniel Bristot de Oliveira struct trace_seq *s = &iter->seq;
1461a955d7eaSDaniel Bristot de Oliveira struct timerlat_entry *field;
1462a955d7eaSDaniel Bristot de Oliveira
1463a955d7eaSDaniel Bristot de Oliveira trace_assign_type(field, entry);
1464a955d7eaSDaniel Bristot de Oliveira
1465a955d7eaSDaniel Bristot de Oliveira trace_seq_printf(s, "#%-5u context %6s timer_latency %9llu ns\n",
1466a955d7eaSDaniel Bristot de Oliveira field->seqnum,
1467e88ed227SDaniel Bristot de Oliveira timerlat_lat_context[field->context],
1468a955d7eaSDaniel Bristot de Oliveira field->timer_latency);
1469a955d7eaSDaniel Bristot de Oliveira
1470a955d7eaSDaniel Bristot de Oliveira return trace_handle_return(s);
1471a955d7eaSDaniel Bristot de Oliveira }
1472a955d7eaSDaniel Bristot de Oliveira
1473a955d7eaSDaniel Bristot de Oliveira static enum print_line_t
trace_timerlat_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1474a955d7eaSDaniel Bristot de Oliveira trace_timerlat_raw(struct trace_iterator *iter, int flags,
1475a955d7eaSDaniel Bristot de Oliveira struct trace_event *event)
1476a955d7eaSDaniel Bristot de Oliveira {
1477a955d7eaSDaniel Bristot de Oliveira struct timerlat_entry *field;
1478a955d7eaSDaniel Bristot de Oliveira struct trace_seq *s = &iter->seq;
1479a955d7eaSDaniel Bristot de Oliveira
1480a955d7eaSDaniel Bristot de Oliveira trace_assign_type(field, iter->ent);
1481a955d7eaSDaniel Bristot de Oliveira
1482a955d7eaSDaniel Bristot de Oliveira trace_seq_printf(s, "%u %d %llu\n",
1483a955d7eaSDaniel Bristot de Oliveira field->seqnum,
1484a955d7eaSDaniel Bristot de Oliveira field->context,
1485a955d7eaSDaniel Bristot de Oliveira field->timer_latency);
1486a955d7eaSDaniel Bristot de Oliveira
1487a955d7eaSDaniel Bristot de Oliveira return trace_handle_return(s);
1488a955d7eaSDaniel Bristot de Oliveira }
1489a955d7eaSDaniel Bristot de Oliveira
1490a955d7eaSDaniel Bristot de Oliveira static struct trace_event_functions trace_timerlat_funcs = {
1491a955d7eaSDaniel Bristot de Oliveira .trace = trace_timerlat_print,
1492a955d7eaSDaniel Bristot de Oliveira .raw = trace_timerlat_raw,
1493a955d7eaSDaniel Bristot de Oliveira };
1494a955d7eaSDaniel Bristot de Oliveira
1495a955d7eaSDaniel Bristot de Oliveira static struct trace_event trace_timerlat_event = {
1496a955d7eaSDaniel Bristot de Oliveira .type = TRACE_TIMERLAT,
1497a955d7eaSDaniel Bristot de Oliveira .funcs = &trace_timerlat_funcs,
1498a955d7eaSDaniel Bristot de Oliveira };
1499a955d7eaSDaniel Bristot de Oliveira
150009ae7234SSteven Rostedt (Red Hat) /* TRACE_BPUTS */
150109ae7234SSteven Rostedt (Red Hat) static enum print_line_t
trace_bputs_print(struct trace_iterator * iter,int flags,struct trace_event * event)150209ae7234SSteven Rostedt (Red Hat) trace_bputs_print(struct trace_iterator *iter, int flags,
150309ae7234SSteven Rostedt (Red Hat) struct trace_event *event)
150409ae7234SSteven Rostedt (Red Hat) {
150509ae7234SSteven Rostedt (Red Hat) struct trace_entry *entry = iter->ent;
150609ae7234SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
150709ae7234SSteven Rostedt (Red Hat) struct bputs_entry *field;
150809ae7234SSteven Rostedt (Red Hat)
150909ae7234SSteven Rostedt (Red Hat) trace_assign_type(field, entry);
151009ae7234SSteven Rostedt (Red Hat)
151119a7fe20SSteven Rostedt (Red Hat) seq_print_ip_sym(s, field->ip, flags);
151219a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, ": ");
151319a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, field->str);
151409ae7234SSteven Rostedt (Red Hat)
151519a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
151609ae7234SSteven Rostedt (Red Hat) }
151709ae7234SSteven Rostedt (Red Hat)
151809ae7234SSteven Rostedt (Red Hat)
151909ae7234SSteven Rostedt (Red Hat) static enum print_line_t
trace_bputs_raw(struct trace_iterator * iter,int flags,struct trace_event * event)152009ae7234SSteven Rostedt (Red Hat) trace_bputs_raw(struct trace_iterator *iter, int flags,
152109ae7234SSteven Rostedt (Red Hat) struct trace_event *event)
152209ae7234SSteven Rostedt (Red Hat) {
152309ae7234SSteven Rostedt (Red Hat) struct bputs_entry *field;
152409ae7234SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
152509ae7234SSteven Rostedt (Red Hat)
152609ae7234SSteven Rostedt (Red Hat) trace_assign_type(field, iter->ent);
152709ae7234SSteven Rostedt (Red Hat)
152819a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, ": %lx : ", field->ip);
152919a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, field->str);
153009ae7234SSteven Rostedt (Red Hat)
153119a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
153209ae7234SSteven Rostedt (Red Hat) }
153309ae7234SSteven Rostedt (Red Hat)
153409ae7234SSteven Rostedt (Red Hat) static struct trace_event_functions trace_bputs_funcs = {
153509ae7234SSteven Rostedt (Red Hat) .trace = trace_bputs_print,
153609ae7234SSteven Rostedt (Red Hat) .raw = trace_bputs_raw,
153709ae7234SSteven Rostedt (Red Hat) };
153809ae7234SSteven Rostedt (Red Hat)
153909ae7234SSteven Rostedt (Red Hat) static struct trace_event trace_bputs_event = {
154009ae7234SSteven Rostedt (Red Hat) .type = TRACE_BPUTS,
154109ae7234SSteven Rostedt (Red Hat) .funcs = &trace_bputs_funcs,
154209ae7234SSteven Rostedt (Red Hat) };
154309ae7234SSteven Rostedt (Red Hat)
154448ead020SFrederic Weisbecker /* TRACE_BPRINT */
15451427cdf0SLai Jiangshan static enum print_line_t
trace_bprint_print(struct trace_iterator * iter,int flags,struct trace_event * event)1546a9a57763SSteven Rostedt trace_bprint_print(struct trace_iterator *iter, int flags,
1547a9a57763SSteven Rostedt struct trace_event *event)
15481427cdf0SLai Jiangshan {
15491427cdf0SLai Jiangshan struct trace_entry *entry = iter->ent;
15501427cdf0SLai Jiangshan struct trace_seq *s = &iter->seq;
155148ead020SFrederic Weisbecker struct bprint_entry *field;
15521427cdf0SLai Jiangshan
15531427cdf0SLai Jiangshan trace_assign_type(field, entry);
15541427cdf0SLai Jiangshan
155519a7fe20SSteven Rostedt (Red Hat) seq_print_ip_sym(s, field->ip, flags);
155619a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, ": ");
155719a7fe20SSteven Rostedt (Red Hat) trace_seq_bprintf(s, field->fmt, field->buf);
15581427cdf0SLai Jiangshan
155919a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
15601427cdf0SLai Jiangshan }
15611427cdf0SLai Jiangshan
15621427cdf0SLai Jiangshan
156348ead020SFrederic Weisbecker static enum print_line_t
trace_bprint_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1564a9a57763SSteven Rostedt trace_bprint_raw(struct trace_iterator *iter, int flags,
1565a9a57763SSteven Rostedt struct trace_event *event)
1566769b0441SFrederic Weisbecker {
156748ead020SFrederic Weisbecker struct bprint_entry *field;
1568769b0441SFrederic Weisbecker struct trace_seq *s = &iter->seq;
1569769b0441SFrederic Weisbecker
1570769b0441SFrederic Weisbecker trace_assign_type(field, iter->ent);
15711427cdf0SLai Jiangshan
157219a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, ": %lx : ", field->ip);
157319a7fe20SSteven Rostedt (Red Hat) trace_seq_bprintf(s, field->fmt, field->buf);
15741427cdf0SLai Jiangshan
157519a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
15761427cdf0SLai Jiangshan }
15771427cdf0SLai Jiangshan
1578a9a57763SSteven Rostedt static struct trace_event_functions trace_bprint_funcs = {
157948ead020SFrederic Weisbecker .trace = trace_bprint_print,
158048ead020SFrederic Weisbecker .raw = trace_bprint_raw,
158148ead020SFrederic Weisbecker };
158248ead020SFrederic Weisbecker
1583a9a57763SSteven Rostedt static struct trace_event trace_bprint_event = {
1584a9a57763SSteven Rostedt .type = TRACE_BPRINT,
1585a9a57763SSteven Rostedt .funcs = &trace_bprint_funcs,
1586a9a57763SSteven Rostedt };
1587a9a57763SSteven Rostedt
158848ead020SFrederic Weisbecker /* TRACE_PRINT */
trace_print_print(struct trace_iterator * iter,int flags,struct trace_event * event)158948ead020SFrederic Weisbecker static enum print_line_t trace_print_print(struct trace_iterator *iter,
1590a9a57763SSteven Rostedt int flags, struct trace_event *event)
159148ead020SFrederic Weisbecker {
159248ead020SFrederic Weisbecker struct print_entry *field;
159348ead020SFrederic Weisbecker struct trace_seq *s = &iter->seq;
159448ead020SFrederic Weisbecker
159548ead020SFrederic Weisbecker trace_assign_type(field, iter->ent);
159648ead020SFrederic Weisbecker
159719a7fe20SSteven Rostedt (Red Hat) seq_print_ip_sym(s, field->ip, flags);
1598e87cb9ddSSteven Rostedt (Google) trace_seq_printf(s, ": %s", field->buf);
159948ead020SFrederic Weisbecker
160019a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
160148ead020SFrederic Weisbecker }
160248ead020SFrederic Weisbecker
trace_print_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1603a9a57763SSteven Rostedt static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags,
1604a9a57763SSteven Rostedt struct trace_event *event)
160548ead020SFrederic Weisbecker {
160648ead020SFrederic Weisbecker struct print_entry *field;
160748ead020SFrederic Weisbecker
160848ead020SFrederic Weisbecker trace_assign_type(field, iter->ent);
160948ead020SFrederic Weisbecker
1610e87cb9ddSSteven Rostedt (Google) trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf);
161148ead020SFrederic Weisbecker
161219a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
161348ead020SFrederic Weisbecker }
161448ead020SFrederic Weisbecker
1615a9a57763SSteven Rostedt static struct trace_event_functions trace_print_funcs = {
1616769b0441SFrederic Weisbecker .trace = trace_print_print,
1617769b0441SFrederic Weisbecker .raw = trace_print_raw,
16181427cdf0SLai Jiangshan };
16191427cdf0SLai Jiangshan
1620a9a57763SSteven Rostedt static struct trace_event trace_print_event = {
1621a9a57763SSteven Rostedt .type = TRACE_PRINT,
1622a9a57763SSteven Rostedt .funcs = &trace_print_funcs,
1623a9a57763SSteven Rostedt };
1624a9a57763SSteven Rostedt
trace_raw_data(struct trace_iterator * iter,int flags,struct trace_event * event)1625fa32e855SSteven Rostedt static enum print_line_t trace_raw_data(struct trace_iterator *iter, int flags,
1626fa32e855SSteven Rostedt struct trace_event *event)
1627fa32e855SSteven Rostedt {
1628fa32e855SSteven Rostedt struct raw_data_entry *field;
1629fa32e855SSteven Rostedt int i;
1630fa32e855SSteven Rostedt
1631fa32e855SSteven Rostedt trace_assign_type(field, iter->ent);
1632fa32e855SSteven Rostedt
1633fa32e855SSteven Rostedt trace_seq_printf(&iter->seq, "# %x buf:", field->id);
1634fa32e855SSteven Rostedt
1635fa32e855SSteven Rostedt for (i = 0; i < iter->ent_size - offsetof(struct raw_data_entry, buf); i++)
1636fa32e855SSteven Rostedt trace_seq_printf(&iter->seq, " %02x",
1637fa32e855SSteven Rostedt (unsigned char)field->buf[i]);
1638fa32e855SSteven Rostedt
1639fa32e855SSteven Rostedt trace_seq_putc(&iter->seq, '\n');
1640fa32e855SSteven Rostedt
1641fa32e855SSteven Rostedt return trace_handle_return(&iter->seq);
1642fa32e855SSteven Rostedt }
1643fa32e855SSteven Rostedt
1644fa32e855SSteven Rostedt static struct trace_event_functions trace_raw_data_funcs = {
1645fa32e855SSteven Rostedt .trace = trace_raw_data,
1646fa32e855SSteven Rostedt .raw = trace_raw_data,
1647fa32e855SSteven Rostedt };
1648fa32e855SSteven Rostedt
1649fa32e855SSteven Rostedt static struct trace_event trace_raw_data_event = {
1650fa32e855SSteven Rostedt .type = TRACE_RAW_DATA,
1651fa32e855SSteven Rostedt .funcs = &trace_raw_data_funcs,
1652fa32e855SSteven Rostedt };
1653fa32e855SSteven Rostedt
1654f689e4f2SYordan Karadzhov (VMware) static enum print_line_t
trace_func_repeats_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1655f689e4f2SYordan Karadzhov (VMware) trace_func_repeats_raw(struct trace_iterator *iter, int flags,
1656f689e4f2SYordan Karadzhov (VMware) struct trace_event *event)
1657f689e4f2SYordan Karadzhov (VMware) {
1658f689e4f2SYordan Karadzhov (VMware) struct func_repeats_entry *field;
1659f689e4f2SYordan Karadzhov (VMware) struct trace_seq *s = &iter->seq;
1660f689e4f2SYordan Karadzhov (VMware)
1661f689e4f2SYordan Karadzhov (VMware) trace_assign_type(field, iter->ent);
1662f689e4f2SYordan Karadzhov (VMware)
1663f689e4f2SYordan Karadzhov (VMware) trace_seq_printf(s, "%lu %lu %u %llu\n",
1664f689e4f2SYordan Karadzhov (VMware) field->ip,
1665f689e4f2SYordan Karadzhov (VMware) field->parent_ip,
1666f689e4f2SYordan Karadzhov (VMware) field->count,
1667f689e4f2SYordan Karadzhov (VMware) FUNC_REPEATS_GET_DELTA_TS(field));
1668f689e4f2SYordan Karadzhov (VMware)
1669f689e4f2SYordan Karadzhov (VMware) return trace_handle_return(s);
1670f689e4f2SYordan Karadzhov (VMware) }
1671f689e4f2SYordan Karadzhov (VMware)
1672f689e4f2SYordan Karadzhov (VMware) static enum print_line_t
trace_func_repeats_print(struct trace_iterator * iter,int flags,struct trace_event * event)1673f689e4f2SYordan Karadzhov (VMware) trace_func_repeats_print(struct trace_iterator *iter, int flags,
1674f689e4f2SYordan Karadzhov (VMware) struct trace_event *event)
1675f689e4f2SYordan Karadzhov (VMware) {
1676f689e4f2SYordan Karadzhov (VMware) struct func_repeats_entry *field;
1677f689e4f2SYordan Karadzhov (VMware) struct trace_seq *s = &iter->seq;
1678f689e4f2SYordan Karadzhov (VMware)
1679f689e4f2SYordan Karadzhov (VMware) trace_assign_type(field, iter->ent);
1680f689e4f2SYordan Karadzhov (VMware)
1681e1db6338SSteven Rostedt (VMware) print_fn_trace(s, field->ip, field->parent_ip, flags);
1682f689e4f2SYordan Karadzhov (VMware) trace_seq_printf(s, " (repeats: %u, last_ts:", field->count);
1683f689e4f2SYordan Karadzhov (VMware) trace_print_time(s, iter,
1684f689e4f2SYordan Karadzhov (VMware) iter->ts - FUNC_REPEATS_GET_DELTA_TS(field));
1685f689e4f2SYordan Karadzhov (VMware) trace_seq_puts(s, ")\n");
1686f689e4f2SYordan Karadzhov (VMware)
1687f689e4f2SYordan Karadzhov (VMware) return trace_handle_return(s);
1688f689e4f2SYordan Karadzhov (VMware) }
1689f689e4f2SYordan Karadzhov (VMware)
1690f689e4f2SYordan Karadzhov (VMware) static struct trace_event_functions trace_func_repeats_funcs = {
1691f689e4f2SYordan Karadzhov (VMware) .trace = trace_func_repeats_print,
1692f689e4f2SYordan Karadzhov (VMware) .raw = trace_func_repeats_raw,
1693f689e4f2SYordan Karadzhov (VMware) };
1694f689e4f2SYordan Karadzhov (VMware)
1695f689e4f2SYordan Karadzhov (VMware) static struct trace_event trace_func_repeats_event = {
1696f689e4f2SYordan Karadzhov (VMware) .type = TRACE_FUNC_REPEATS,
1697f689e4f2SYordan Karadzhov (VMware) .funcs = &trace_func_repeats_funcs,
1698f689e4f2SYordan Karadzhov (VMware) };
169948ead020SFrederic Weisbecker
1700f633cef0SSteven Rostedt static struct trace_event *events[] __initdata = {
1701f633cef0SSteven Rostedt &trace_fn_event,
1702f633cef0SSteven Rostedt &trace_ctx_event,
1703f633cef0SSteven Rostedt &trace_wake_event,
1704f633cef0SSteven Rostedt &trace_stack_event,
1705f633cef0SSteven Rostedt &trace_user_stack_event,
170609ae7234SSteven Rostedt (Red Hat) &trace_bputs_event,
170748ead020SFrederic Weisbecker &trace_bprint_event,
1708f633cef0SSteven Rostedt &trace_print_event,
1709e7c15cd8SSteven Rostedt (Red Hat) &trace_hwlat_event,
1710bce29ac9SDaniel Bristot de Oliveira &trace_osnoise_event,
1711a955d7eaSDaniel Bristot de Oliveira &trace_timerlat_event,
1712fa32e855SSteven Rostedt &trace_raw_data_event,
1713f689e4f2SYordan Karadzhov (VMware) &trace_func_repeats_event,
1714f633cef0SSteven Rostedt NULL
1715f633cef0SSteven Rostedt };
1716f633cef0SSteven Rostedt
init_events(void)17173bb06eb6SSteven Rostedt (Google) __init int init_events(void)
1718f633cef0SSteven Rostedt {
1719f633cef0SSteven Rostedt struct trace_event *event;
1720f633cef0SSteven Rostedt int i, ret;
1721f633cef0SSteven Rostedt
1722f633cef0SSteven Rostedt for (i = 0; events[i]; i++) {
1723f633cef0SSteven Rostedt event = events[i];
17249023c930SSteven Rostedt (Red Hat) ret = register_trace_event(event);
17254ee51101SGuo Zhengkui WARN_ONCE(!ret, "event %d failed to register", event->type);
1726f633cef0SSteven Rostedt }
1727f633cef0SSteven Rostedt
1728f633cef0SSteven Rostedt return 0;
1729f633cef0SSteven Rostedt }
1730