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 <[email protected]>
6f0868d1eSSteven Rostedt *
7f0868d1eSSteven Rostedt */
835a380ddSMasami Hiramatsu (Google) #include "trace.h"
9f0868d1eSSteven Rostedt #include <linux/module.h>
10f0868d1eSSteven Rostedt #include <linux/mutex.h>
11f0868d1eSSteven Rostedt #include <linux/ftrace.h>
127da89495SMasami Hiramatsu #include <linux/kprobes.h>
13e6017571SIngo Molnar #include <linux/sched/clock.h>
146e84f315SIngo Molnar #include <linux/sched/mm.h>
1596e6122cSZheng Yejian #include <linux/idr.h>
16533c20b0SSven Schnelle #include <linux/btf.h>
17533c20b0SSven Schnelle #include <linux/bpf.h>
18391dda1bSSasha Levin #include <linux/hashtable.h>
19f0868d1eSSteven Rostedt
20f0868d1eSSteven Rostedt #include "trace_output.h"
21533c20b0SSven Schnelle #include "trace_btf.h"
22f0868d1eSSteven Rostedt
23391dda1bSSasha Levin /* 2^7 = 128 */
24391dda1bSSasha Levin #define EVENT_HASH_BITS 7
25f0868d1eSSteven Rostedt
2652f6ad6dSzhangwei(Jovi) DECLARE_RWSEM(trace_event_sem);
27be74b73aSSteven Rostedt
28391dda1bSSasha Levin static DEFINE_HASHTABLE(event_hash, EVENT_HASH_BITS);
29f0868d1eSSteven Rostedt
trace_print_bputs_msg_only(struct trace_iterator * iter)3009ae7234SSteven Rostedt (Red Hat) enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter)
3109ae7234SSteven Rostedt (Red Hat) {
3209ae7234SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
3309ae7234SSteven Rostedt (Red Hat) struct trace_entry *entry = iter->ent;
3409ae7234SSteven Rostedt (Red Hat) struct bputs_entry *field;
3509ae7234SSteven Rostedt (Red Hat)
3609ae7234SSteven Rostedt (Red Hat) trace_assign_type(field, entry);
3709ae7234SSteven Rostedt (Red Hat)
3819a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, field->str);
3909ae7234SSteven Rostedt (Red Hat)
4019a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
4109ae7234SSteven Rostedt (Red Hat) }
4209ae7234SSteven Rostedt (Red Hat)
trace_print_bprintk_msg_only(struct trace_iterator * iter)435ef841f6SSteven Rostedt enum print_line_t trace_print_bprintk_msg_only(struct trace_iterator *iter)
445ef841f6SSteven Rostedt {
455ef841f6SSteven Rostedt struct trace_seq *s = &iter->seq;
465ef841f6SSteven Rostedt struct trace_entry *entry = iter->ent;
475ef841f6SSteven Rostedt struct bprint_entry *field;
485ef841f6SSteven Rostedt
495ef841f6SSteven Rostedt trace_assign_type(field, entry);
505ef841f6SSteven Rostedt
5119a7fe20SSteven Rostedt (Red Hat) trace_seq_bprintf(s, field->fmt, field->buf);
525ef841f6SSteven Rostedt
5319a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
545ef841f6SSteven Rostedt }
555ef841f6SSteven Rostedt
trace_print_printk_msg_only(struct trace_iterator * iter)565ef841f6SSteven Rostedt enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
575ef841f6SSteven Rostedt {
585ef841f6SSteven Rostedt struct trace_seq *s = &iter->seq;
595ef841f6SSteven Rostedt struct trace_entry *entry = iter->ent;
605ef841f6SSteven Rostedt struct print_entry *field;
615ef841f6SSteven Rostedt
625ef841f6SSteven Rostedt trace_assign_type(field, entry);
635ef841f6SSteven Rostedt
6419a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, field->buf);
655ef841f6SSteven Rostedt
6619a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
675ef841f6SSteven Rostedt }
685ef841f6SSteven Rostedt
69be74b73aSSteven Rostedt const char *
trace_print_flags_seq(struct trace_seq * p,const char * delim,unsigned long flags,const struct trace_print_flags * flag_array)70645df987SSteven Rostedt (Red Hat) trace_print_flags_seq(struct trace_seq *p, const char *delim,
71be74b73aSSteven Rostedt unsigned long flags,
72be74b73aSSteven Rostedt const struct trace_print_flags *flag_array)
73be74b73aSSteven Rostedt {
74be74b73aSSteven Rostedt unsigned long mask;
75be74b73aSSteven Rostedt const char *str;
767b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
77e404b321SAndrey Vagin int i, first = 1;
78be74b73aSSteven Rostedt
79be74b73aSSteven Rostedt for (i = 0; flag_array[i].name && flags; i++) {
80be74b73aSSteven Rostedt
81be74b73aSSteven Rostedt mask = flag_array[i].mask;
82be74b73aSSteven Rostedt if ((flags & mask) != mask)
83be74b73aSSteven Rostedt continue;
84be74b73aSSteven Rostedt
85be74b73aSSteven Rostedt str = flag_array[i].name;
86be74b73aSSteven Rostedt flags &= ~mask;
87e404b321SAndrey Vagin if (!first && delim)
88be74b73aSSteven Rostedt trace_seq_puts(p, delim);
89e404b321SAndrey Vagin else
90e404b321SAndrey Vagin first = 0;
91be74b73aSSteven Rostedt trace_seq_puts(p, str);
92be74b73aSSteven Rostedt }
93be74b73aSSteven Rostedt
94be74b73aSSteven Rostedt /* check for left over flags */
95be74b73aSSteven Rostedt if (flags) {
965b349261SSteven Rostedt if (!first && delim)
97be74b73aSSteven Rostedt trace_seq_puts(p, delim);
98be74b73aSSteven Rostedt trace_seq_printf(p, "0x%lx", flags);
99be74b73aSSteven Rostedt }
100be74b73aSSteven Rostedt
101be74b73aSSteven Rostedt trace_seq_putc(p, 0);
102be74b73aSSteven Rostedt
10356d8bd3fSSteven Whitehouse return ret;
104be74b73aSSteven Rostedt }
105645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_flags_seq);
106be74b73aSSteven Rostedt
1070f4fc29dSSteven Rostedt const char *
trace_print_symbols_seq(struct trace_seq * p,unsigned long val,const struct trace_print_flags * symbol_array)108645df987SSteven Rostedt (Red Hat) trace_print_symbols_seq(struct trace_seq *p, unsigned long val,
1090f4fc29dSSteven Rostedt const struct trace_print_flags *symbol_array)
1100f4fc29dSSteven Rostedt {
1110f4fc29dSSteven Rostedt int i;
1127b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
1130f4fc29dSSteven Rostedt
1140f4fc29dSSteven Rostedt for (i = 0; symbol_array[i].name; i++) {
1150f4fc29dSSteven Rostedt
1160f4fc29dSSteven Rostedt if (val != symbol_array[i].mask)
1170f4fc29dSSteven Rostedt continue;
1180f4fc29dSSteven Rostedt
1190f4fc29dSSteven Rostedt trace_seq_puts(p, symbol_array[i].name);
1200f4fc29dSSteven Rostedt break;
1210f4fc29dSSteven Rostedt }
1220f4fc29dSSteven Rostedt
1237b039cb4SSteven Rostedt (Red Hat) if (ret == (const char *)(trace_seq_buffer_ptr(p)))
1240f4fc29dSSteven Rostedt trace_seq_printf(p, "0x%lx", val);
1250f4fc29dSSteven Rostedt
1260f4fc29dSSteven Rostedt trace_seq_putc(p, 0);
1270f4fc29dSSteven Rostedt
12856d8bd3fSSteven Whitehouse return ret;
1290f4fc29dSSteven Rostedt }
130645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_symbols_seq);
1310f4fc29dSSteven Rostedt
1322fc1b6f0Sliubo #if BITS_PER_LONG == 32
1332fc1b6f0Sliubo 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)134d3213e8fSRoss Zwisler trace_print_flags_seq_u64(struct trace_seq *p, const char *delim,
135d3213e8fSRoss Zwisler unsigned long long flags,
136d3213e8fSRoss Zwisler const struct trace_print_flags_u64 *flag_array)
137d3213e8fSRoss Zwisler {
138d3213e8fSRoss Zwisler unsigned long long mask;
139d3213e8fSRoss Zwisler const char *str;
140d3213e8fSRoss Zwisler const char *ret = trace_seq_buffer_ptr(p);
141d3213e8fSRoss Zwisler int i, first = 1;
142d3213e8fSRoss Zwisler
143d3213e8fSRoss Zwisler for (i = 0; flag_array[i].name && flags; i++) {
144d3213e8fSRoss Zwisler
145d3213e8fSRoss Zwisler mask = flag_array[i].mask;
146d3213e8fSRoss Zwisler if ((flags & mask) != mask)
147d3213e8fSRoss Zwisler continue;
148d3213e8fSRoss Zwisler
149d3213e8fSRoss Zwisler str = flag_array[i].name;
150d3213e8fSRoss Zwisler flags &= ~mask;
151d3213e8fSRoss Zwisler if (!first && delim)
152d3213e8fSRoss Zwisler trace_seq_puts(p, delim);
153d3213e8fSRoss Zwisler else
154d3213e8fSRoss Zwisler first = 0;
155d3213e8fSRoss Zwisler trace_seq_puts(p, str);
156d3213e8fSRoss Zwisler }
157d3213e8fSRoss Zwisler
158d3213e8fSRoss Zwisler /* check for left over flags */
159d3213e8fSRoss Zwisler if (flags) {
160d3213e8fSRoss Zwisler if (!first && delim)
161d3213e8fSRoss Zwisler trace_seq_puts(p, delim);
162d3213e8fSRoss Zwisler trace_seq_printf(p, "0x%llx", flags);
163d3213e8fSRoss Zwisler }
164d3213e8fSRoss Zwisler
165d3213e8fSRoss Zwisler trace_seq_putc(p, 0);
166d3213e8fSRoss Zwisler
167d3213e8fSRoss Zwisler return ret;
168d3213e8fSRoss Zwisler }
169d3213e8fSRoss Zwisler EXPORT_SYMBOL(trace_print_flags_seq_u64);
170d3213e8fSRoss Zwisler
171d3213e8fSRoss Zwisler const char *
trace_print_symbols_seq_u64(struct trace_seq * p,unsigned long long val,const struct trace_print_flags_u64 * symbol_array)172645df987SSteven Rostedt (Red Hat) trace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
1732fc1b6f0Sliubo const struct trace_print_flags_u64 *symbol_array)
1742fc1b6f0Sliubo {
1752fc1b6f0Sliubo int i;
1767b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
1772fc1b6f0Sliubo
1782fc1b6f0Sliubo for (i = 0; symbol_array[i].name; i++) {
1792fc1b6f0Sliubo
1802fc1b6f0Sliubo if (val != symbol_array[i].mask)
1812fc1b6f0Sliubo continue;
1822fc1b6f0Sliubo
1832fc1b6f0Sliubo trace_seq_puts(p, symbol_array[i].name);
1842fc1b6f0Sliubo break;
1852fc1b6f0Sliubo }
1862fc1b6f0Sliubo
1877b039cb4SSteven Rostedt (Red Hat) if (ret == (const char *)(trace_seq_buffer_ptr(p)))
1882fc1b6f0Sliubo trace_seq_printf(p, "0x%llx", val);
1892fc1b6f0Sliubo
1902fc1b6f0Sliubo trace_seq_putc(p, 0);
1912fc1b6f0Sliubo
1922fc1b6f0Sliubo return ret;
1932fc1b6f0Sliubo }
194645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_symbols_seq_u64);
1952fc1b6f0Sliubo #endif
1962fc1b6f0Sliubo
1975a2e3995SKei Tokunaga const char *
trace_print_bitmask_seq(struct trace_seq * p,void * bitmask_ptr,unsigned int bitmask_size)198645df987SSteven Rostedt (Red Hat) trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr,
1994449bf92SSteven Rostedt (Red Hat) unsigned int bitmask_size)
2004449bf92SSteven Rostedt (Red Hat) {
2017b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
2024449bf92SSteven Rostedt (Red Hat)
2034449bf92SSteven Rostedt (Red Hat) trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8);
2044449bf92SSteven Rostedt (Red Hat) trace_seq_putc(p, 0);
2054449bf92SSteven Rostedt (Red Hat)
2064449bf92SSteven Rostedt (Red Hat) return ret;
2074449bf92SSteven Rostedt (Red Hat) }
208645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(trace_print_bitmask_seq);
2094449bf92SSteven Rostedt (Red Hat)
2103898fac1SDaniel Borkmann /**
2113898fac1SDaniel Borkmann * trace_print_hex_seq - print buffer as hex sequence
2123898fac1SDaniel Borkmann * @p: trace seq struct to write to
2133898fac1SDaniel Borkmann * @buf: The buffer to print
2143898fac1SDaniel Borkmann * @buf_len: Length of @buf in bytes
2153898fac1SDaniel Borkmann * @concatenate: Print @buf as single hex string or with spacing
2163898fac1SDaniel Borkmann *
2173898fac1SDaniel Borkmann * Prints the passed buffer as a hex sequence either as a whole,
2183898fac1SDaniel Borkmann * single hex string if @concatenate is true or with spacing after
2193898fac1SDaniel Borkmann * each byte in case @concatenate is false.
2203898fac1SDaniel Borkmann */
2214449bf92SSteven Rostedt (Red Hat) const char *
trace_print_hex_seq(struct trace_seq * p,const unsigned char * buf,int buf_len,bool concatenate)2222acae0d5SDaniel Borkmann trace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len,
2233898fac1SDaniel Borkmann bool concatenate)
2245a2e3995SKei Tokunaga {
2255a2e3995SKei Tokunaga int i;
2267b039cb4SSteven Rostedt (Red Hat) const char *ret = trace_seq_buffer_ptr(p);
227119cdbdbSAndy Shevchenko const char *fmt = concatenate ? "%*phN" : "%*ph";
2285a2e3995SKei Tokunaga
229adace440SKen Lin for (i = 0; i < buf_len; i += 16) {
230adace440SKen Lin if (!concatenate && i != 0)
231adace440SKen Lin trace_seq_putc(p, ' ');
232119cdbdbSAndy Shevchenko trace_seq_printf(p, fmt, min(buf_len - i, 16), &buf[i]);
233adace440SKen Lin }
2345a2e3995SKei Tokunaga trace_seq_putc(p, 0);
2355a2e3995SKei Tokunaga
2365a2e3995SKei Tokunaga return ret;
2375a2e3995SKei Tokunaga }
238645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_hex_seq);
2395a2e3995SKei Tokunaga
2406ea22486SDave Martin const char *
trace_print_array_seq(struct trace_seq * p,const void * buf,int count,size_t el_size)241645df987SSteven Rostedt (Red Hat) trace_print_array_seq(struct trace_seq *p, const void *buf, int count,
2426ea22486SDave Martin size_t el_size)
2436ea22486SDave Martin {
2446ea22486SDave Martin const char *ret = trace_seq_buffer_ptr(p);
2456ea22486SDave Martin const char *prefix = "";
2466ea22486SDave Martin void *ptr = (void *)buf;
247ac01ce14SAlex Bennée size_t buf_len = count * el_size;
2486ea22486SDave Martin
2496ea22486SDave Martin trace_seq_putc(p, '{');
2506ea22486SDave Martin
2516ea22486SDave Martin while (ptr < buf + buf_len) {
2526ea22486SDave Martin switch (el_size) {
2536ea22486SDave Martin case 1:
2546ea22486SDave Martin trace_seq_printf(p, "%s0x%x", prefix,
2556ea22486SDave Martin *(u8 *)ptr);
2566ea22486SDave Martin break;
2576ea22486SDave Martin case 2:
2586ea22486SDave Martin trace_seq_printf(p, "%s0x%x", prefix,
2596ea22486SDave Martin *(u16 *)ptr);
2606ea22486SDave Martin break;
2616ea22486SDave Martin case 4:
2626ea22486SDave Martin trace_seq_printf(p, "%s0x%x", prefix,
2636ea22486SDave Martin *(u32 *)ptr);
2646ea22486SDave Martin break;
2656ea22486SDave Martin case 8:
2666ea22486SDave Martin trace_seq_printf(p, "%s0x%llx", prefix,
2676ea22486SDave Martin *(u64 *)ptr);
2686ea22486SDave Martin break;
2696ea22486SDave Martin default:
2706ea22486SDave Martin trace_seq_printf(p, "BAD SIZE:%zu 0x%x", el_size,
2716ea22486SDave Martin *(u8 *)ptr);
2726ea22486SDave Martin el_size = 1;
2736ea22486SDave Martin }
2746ea22486SDave Martin prefix = ",";
2756ea22486SDave Martin ptr += el_size;
2766ea22486SDave Martin }
2776ea22486SDave Martin
2786ea22486SDave Martin trace_seq_putc(p, '}');
2796ea22486SDave Martin trace_seq_putc(p, 0);
2806ea22486SDave Martin
2816ea22486SDave Martin return ret;
2826ea22486SDave Martin }
283645df987SSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_print_array_seq);
2846ea22486SDave Martin
285ef56e047SPiotr 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)286ef56e047SPiotr Maziarz trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str,
287ef56e047SPiotr Maziarz int prefix_type, int rowsize, int groupsize,
288ef56e047SPiotr Maziarz const void *buf, size_t len, bool ascii)
289ef56e047SPiotr Maziarz {
290ef56e047SPiotr Maziarz const char *ret = trace_seq_buffer_ptr(p);
291ef56e047SPiotr Maziarz
292ef56e047SPiotr Maziarz trace_seq_putc(p, '\n');
293ef56e047SPiotr Maziarz trace_seq_hex_dump(p, prefix_str, prefix_type,
294ef56e047SPiotr Maziarz rowsize, groupsize, buf, len, ascii);
295ef56e047SPiotr Maziarz trace_seq_putc(p, 0);
296ef56e047SPiotr Maziarz return ret;
297ef56e047SPiotr Maziarz }
298ef56e047SPiotr Maziarz EXPORT_SYMBOL(trace_print_hex_dump_seq);
299ef56e047SPiotr Maziarz
trace_raw_output_prep(struct trace_iterator * iter,struct trace_event * trace_event)300892c505aSSteven Rostedt (Red Hat) int trace_raw_output_prep(struct trace_iterator *iter,
301f71130deSLi Zefan struct trace_event *trace_event)
302f71130deSLi Zefan {
3032425bcb9SSteven Rostedt (Red Hat) struct trace_event_call *event;
304f71130deSLi Zefan struct trace_seq *s = &iter->seq;
305f71130deSLi Zefan struct trace_seq *p = &iter->tmp_seq;
306f71130deSLi Zefan struct trace_entry *entry;
307f71130deSLi Zefan
3082425bcb9SSteven Rostedt (Red Hat) event = container_of(trace_event, struct trace_event_call, event);
309f71130deSLi Zefan entry = iter->ent;
310f71130deSLi Zefan
311f71130deSLi Zefan if (entry->type != event->event.type) {
312f71130deSLi Zefan WARN_ON_ONCE(1);
313f71130deSLi Zefan return TRACE_TYPE_UNHANDLED;
314f71130deSLi Zefan }
315f71130deSLi Zefan
316f71130deSLi Zefan trace_seq_init(p);
317687fcc4aSSteven Rostedt (Red Hat) trace_seq_printf(s, "%s: ", trace_event_name(event));
31819a7fe20SSteven Rostedt (Red Hat)
3198e2e095cSSteven Rostedt (Red Hat) return trace_handle_return(s);
320f71130deSLi Zefan }
321892c505aSSteven Rostedt (Red Hat) EXPORT_SYMBOL(trace_raw_output_prep);
322f71130deSLi Zefan
trace_event_printf(struct trace_iterator * iter,const char * fmt,...)323efbbdaa2SMasami Hiramatsu void trace_event_printf(struct trace_iterator *iter, const char *fmt, ...)
324efbbdaa2SMasami Hiramatsu {
325afd2627fSSteven Rostedt struct trace_seq *s = &iter->seq;
326efbbdaa2SMasami Hiramatsu va_list ap;
327efbbdaa2SMasami Hiramatsu
328afd2627fSSteven Rostedt if (ignore_event(iter))
329afd2627fSSteven Rostedt return;
330afd2627fSSteven Rostedt
331efbbdaa2SMasami Hiramatsu va_start(ap, fmt);
332afd2627fSSteven Rostedt trace_seq_vprintf(s, trace_event_format(iter, fmt), ap);
333efbbdaa2SMasami Hiramatsu va_end(ap);
334efbbdaa2SMasami Hiramatsu }
335efbbdaa2SMasami Hiramatsu EXPORT_SYMBOL(trace_event_printf);
336efbbdaa2SMasami Hiramatsu
337bfd5a5e8SDavid Howells static __printf(3, 0)
trace_output_raw(struct trace_iterator * iter,char * name,char * fmt,va_list ap)338bfd5a5e8SDavid Howells int trace_output_raw(struct trace_iterator *iter, char *name,
3391d6bae96SSteven Rostedt char *fmt, va_list ap)
3401d6bae96SSteven Rostedt {
3411d6bae96SSteven Rostedt struct trace_seq *s = &iter->seq;
3421d6bae96SSteven Rostedt
34319a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, "%s: ", name);
344efbbdaa2SMasami Hiramatsu trace_seq_vprintf(s, trace_event_format(iter, fmt), ap);
3451d6bae96SSteven Rostedt
34619a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
3471d6bae96SSteven Rostedt }
3481d6bae96SSteven Rostedt
trace_output_call(struct trace_iterator * iter,char * name,char * fmt,...)349892c505aSSteven Rostedt (Red Hat) int trace_output_call(struct trace_iterator *iter, char *name, char *fmt, ...)
3501d6bae96SSteven Rostedt {
3511d6bae96SSteven Rostedt va_list ap;
3521d6bae96SSteven Rostedt int ret;
3531d6bae96SSteven Rostedt
3541d6bae96SSteven Rostedt va_start(ap, fmt);
355892c505aSSteven Rostedt (Red Hat) ret = trace_output_raw(iter, name, fmt, ap);
3561d6bae96SSteven Rostedt va_end(ap);
3571d6bae96SSteven Rostedt
3581d6bae96SSteven Rostedt return ret;
3591d6bae96SSteven Rostedt }
360892c505aSSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(trace_output_call);
3611d6bae96SSteven Rostedt
kretprobed(const char * name,unsigned long addr)3627da89495SMasami Hiramatsu static inline const char *kretprobed(const char *name, unsigned long addr)
363f0868d1eSSteven Rostedt {
3647da89495SMasami Hiramatsu if (is_kretprobe_trampoline(addr))
365f0868d1eSSteven Rostedt return "[unknown/kretprobe'd]";
366f0868d1eSSteven Rostedt return name;
367f0868d1eSSteven Rostedt }
368f0868d1eSSteven Rostedt
369773c1670SSteven Rostedt (VMware) void
trace_seq_print_sym(struct trace_seq * s,unsigned long address,bool offset)370773c1670SSteven Rostedt (VMware) trace_seq_print_sym(struct trace_seq *s, unsigned long address, bool offset)
371f0868d1eSSteven Rostedt {
372feaf1283SSteven Rostedt (VMware) #ifdef CONFIG_KALLSYMS
373bea6957dSRasmus Villemoes char str[KSYM_SYMBOL_LEN];
374f0868d1eSSteven Rostedt const char *name;
375f0868d1eSSteven Rostedt
37659dd974bSRasmus Villemoes if (offset)
377f0868d1eSSteven Rostedt sprint_symbol(str, address);
37859dd974bSRasmus Villemoes else
37959dd974bSRasmus Villemoes kallsyms_lookup(address, NULL, NULL, NULL, str);
3807da89495SMasami Hiramatsu name = kretprobed(str, address);
381f0868d1eSSteven Rostedt
382feaf1283SSteven Rostedt (VMware) if (name && strlen(name)) {
383bea6957dSRasmus Villemoes trace_seq_puts(s, name);
384feaf1283SSteven Rostedt (VMware) return;
385feaf1283SSteven Rostedt (VMware) }
386f0868d1eSSteven Rostedt #endif
387bea6957dSRasmus Villemoes trace_seq_printf(s, "0x%08lx", address);
388f0868d1eSSteven Rostedt }
389f0868d1eSSteven Rostedt
390f0868d1eSSteven Rostedt #ifndef CONFIG_64BIT
391f0868d1eSSteven Rostedt # define IP_FMT "%08lx"
392f0868d1eSSteven Rostedt #else
393f0868d1eSSteven Rostedt # define IP_FMT "%016lx"
394f0868d1eSSteven Rostedt #endif
395f0868d1eSSteven Rostedt
seq_print_user_ip(struct trace_seq * s,struct mm_struct * mm,unsigned long ip,unsigned long sym_flags)396ef92480aSSteven Rostedt (Red Hat) static int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,
397f0868d1eSSteven Rostedt unsigned long ip, unsigned long sym_flags)
398f0868d1eSSteven Rostedt {
399f0868d1eSSteven Rostedt struct file *file = NULL;
400f0868d1eSSteven Rostedt unsigned long vmstart = 0;
401f0868d1eSSteven Rostedt int ret = 1;
402f0868d1eSSteven Rostedt
403d184b31cSJohannes Berg if (s->full)
404d184b31cSJohannes Berg return 0;
405d184b31cSJohannes Berg
406f0868d1eSSteven Rostedt if (mm) {
407f0868d1eSSteven Rostedt const struct vm_area_struct *vma;
408f0868d1eSSteven Rostedt
409d8ed45c5SMichel Lespinasse mmap_read_lock(mm);
410f0868d1eSSteven Rostedt vma = find_vma(mm, ip);
411f0868d1eSSteven Rostedt if (vma) {
412f0868d1eSSteven Rostedt file = vma->vm_file;
413f0868d1eSSteven Rostedt vmstart = vma->vm_start;
414f0868d1eSSteven Rostedt }
415f0868d1eSSteven Rostedt if (file) {
41608582d67SAmir Goldstein ret = trace_seq_path(s, file_user_path(file));
417f0868d1eSSteven Rostedt if (ret)
41819a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, "[+0x%lx]",
419f0868d1eSSteven Rostedt ip - vmstart);
420f0868d1eSSteven Rostedt }
421d8ed45c5SMichel Lespinasse mmap_read_unlock(mm);
422f0868d1eSSteven Rostedt }
423f0868d1eSSteven Rostedt if (ret && ((sym_flags & TRACE_ITER_SYM_ADDR) || !file))
42419a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, " <" IP_FMT ">", ip);
42519a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
426f0868d1eSSteven Rostedt }
427f0868d1eSSteven Rostedt
428f0868d1eSSteven Rostedt int
seq_print_ip_sym(struct trace_seq * s,unsigned long ip,unsigned long sym_flags)429f0868d1eSSteven Rostedt seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
430f0868d1eSSteven Rostedt {
43119a7fe20SSteven Rostedt (Red Hat) if (!ip) {
43219a7fe20SSteven Rostedt (Red Hat) trace_seq_putc(s, '0');
43319a7fe20SSteven Rostedt (Red Hat) goto out;
43419a7fe20SSteven Rostedt (Red Hat) }
435f0868d1eSSteven Rostedt
436773c1670SSteven Rostedt (VMware) trace_seq_print_sym(s, ip, sym_flags & TRACE_ITER_SYM_OFFSET);
437f0868d1eSSteven Rostedt
438f0868d1eSSteven Rostedt if (sym_flags & TRACE_ITER_SYM_ADDR)
43919a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, " <" IP_FMT ">", ip);
44019a7fe20SSteven Rostedt (Red Hat)
44119a7fe20SSteven Rostedt (Red Hat) out:
44219a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
443f0868d1eSSteven Rostedt }
444f0868d1eSSteven Rostedt
445f81c972dSSteven Rostedt /**
446f81c972dSSteven Rostedt * trace_print_lat_fmt - print the irq, preempt and lockdep fields
447f81c972dSSteven Rostedt * @s: trace seq struct to write to
448f81c972dSSteven Rostedt * @entry: The trace entry field from the ring buffer
449f81c972dSSteven Rostedt *
450f81c972dSSteven Rostedt * Prints the generic fields of irqs off, in hard or softirq, preempt
451e6e1e259SSteven Rostedt * count.
452f81c972dSSteven Rostedt */
trace_print_lat_fmt(struct trace_seq * s,struct trace_entry * entry)453f81c972dSSteven Rostedt int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
454c4a8e8beSFrederic Weisbecker {
45510da37a6SDavid Sharp char hardsoft_irq;
45610da37a6SDavid Sharp char need_resched;
45710da37a6SDavid Sharp char irqs_off;
45810da37a6SDavid Sharp int hardirq;
45910da37a6SDavid Sharp int softirq;
460289e7b0fSSebastian Andrzej Siewior int bh_off;
4617e6867bfSPeter Zijlstra int nmi;
462c4a8e8beSFrederic Weisbecker
4637e6867bfSPeter Zijlstra nmi = entry->flags & TRACE_FLAG_NMI;
464c4a8e8beSFrederic Weisbecker hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
465c4a8e8beSFrederic Weisbecker softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
466289e7b0fSSebastian Andrzej Siewior bh_off = entry->flags & TRACE_FLAG_BH_OFF;
467d9793bd8SArnaldo Carvalho de Melo
46810da37a6SDavid Sharp irqs_off =
469289e7b0fSSebastian Andrzej Siewior (entry->flags & TRACE_FLAG_IRQS_OFF && bh_off) ? 'D' :
470d9793bd8SArnaldo Carvalho de Melo (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
471289e7b0fSSebastian Andrzej Siewior bh_off ? 'b' :
47210da37a6SDavid Sharp '.';
473e5137b50SPeter Zijlstra
4740172afefSThomas Gleixner switch (entry->flags & (TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY |
475e5137b50SPeter Zijlstra TRACE_FLAG_PREEMPT_RESCHED)) {
4760172afefSThomas Gleixner case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY | TRACE_FLAG_PREEMPT_RESCHED:
4770172afefSThomas Gleixner need_resched = 'B';
4780172afefSThomas Gleixner break;
479e5137b50SPeter Zijlstra case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_PREEMPT_RESCHED:
480e5137b50SPeter Zijlstra need_resched = 'N';
481e5137b50SPeter Zijlstra break;
4820172afefSThomas Gleixner case TRACE_FLAG_NEED_RESCHED_LAZY | TRACE_FLAG_PREEMPT_RESCHED:
4830172afefSThomas Gleixner need_resched = 'L';
4840172afefSThomas Gleixner break;
4850172afefSThomas Gleixner case TRACE_FLAG_NEED_RESCHED | TRACE_FLAG_NEED_RESCHED_LAZY:
4860172afefSThomas Gleixner need_resched = 'b';
4870172afefSThomas Gleixner break;
488e5137b50SPeter Zijlstra case TRACE_FLAG_NEED_RESCHED:
489e5137b50SPeter Zijlstra need_resched = 'n';
490e5137b50SPeter Zijlstra break;
491e5137b50SPeter Zijlstra case TRACE_FLAG_PREEMPT_RESCHED:
492e5137b50SPeter Zijlstra need_resched = 'p';
493e5137b50SPeter Zijlstra break;
4940172afefSThomas Gleixner case TRACE_FLAG_NEED_RESCHED_LAZY:
4950172afefSThomas Gleixner need_resched = 'l';
4960172afefSThomas Gleixner break;
497e5137b50SPeter Zijlstra default:
498e5137b50SPeter Zijlstra need_resched = '.';
499e5137b50SPeter Zijlstra break;
500e5137b50SPeter Zijlstra }
501e5137b50SPeter Zijlstra
50210da37a6SDavid Sharp hardsoft_irq =
5037e6867bfSPeter Zijlstra (nmi && hardirq) ? 'Z' :
5047e6867bfSPeter Zijlstra nmi ? 'z' :
505d9793bd8SArnaldo Carvalho de Melo (hardirq && softirq) ? 'H' :
50610da37a6SDavid Sharp hardirq ? 'h' :
50710da37a6SDavid Sharp softirq ? 's' :
50810da37a6SDavid Sharp '.' ;
50910da37a6SDavid Sharp
51019a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, "%c%c%c",
51119a7fe20SSteven Rostedt (Red Hat) irqs_off, need_resched, hardsoft_irq);
512c4a8e8beSFrederic Weisbecker
51354357f0cSThomas Gleixner if (entry->preempt_count & 0xf)
51454357f0cSThomas Gleixner trace_seq_printf(s, "%x", entry->preempt_count & 0xf);
51554357f0cSThomas Gleixner else
51654357f0cSThomas Gleixner trace_seq_putc(s, '.');
51754357f0cSThomas Gleixner
51854357f0cSThomas Gleixner if (entry->preempt_count & 0xf0)
51954357f0cSThomas Gleixner trace_seq_printf(s, "%x", entry->preempt_count >> 4);
520637e7e86SSteven Rostedt else
52119a7fe20SSteven Rostedt (Red Hat) trace_seq_putc(s, '.');
522829b876dSSteven Rostedt
52319a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
524c4a8e8beSFrederic Weisbecker }
525c4a8e8beSFrederic Weisbecker
526f81c972dSSteven Rostedt static int
lat_print_generic(struct trace_seq * s,struct trace_entry * entry,int cpu)527f81c972dSSteven Rostedt lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
528f81c972dSSteven Rostedt {
529f81c972dSSteven Rostedt char comm[TASK_COMM_LEN];
530f81c972dSSteven Rostedt
531f81c972dSSteven Rostedt trace_find_cmdline(entry->pid, comm);
532f81c972dSSteven Rostedt
533795d6379SSebastian Andrzej Siewior trace_seq_printf(s, "%8.8s-%-7d %3d",
53419a7fe20SSteven Rostedt (Red Hat) comm, entry->pid, cpu);
535f81c972dSSteven Rostedt
536f81c972dSSteven Rostedt return trace_print_lat_fmt(s, entry);
537f81c972dSSteven Rostedt }
538f81c972dSSteven Rostedt
5398e1e1df2SByungchul Park #undef MARK
5408e1e1df2SByungchul Park #define MARK(v, s) {.val = v, .sym = s}
5418e1e1df2SByungchul Park /* trace overhead mark */
5428e1e1df2SByungchul Park static const struct trace_mark {
5438e1e1df2SByungchul Park unsigned long long val; /* unit: nsec */
5448e1e1df2SByungchul Park char sym;
5458e1e1df2SByungchul Park } mark[] = {
5468e1e1df2SByungchul Park MARK(1000000000ULL , '$'), /* 1 sec */
547b838e1d9SJungseok Lee MARK(100000000ULL , '@'), /* 100 msec */
548b838e1d9SJungseok Lee MARK(10000000ULL , '*'), /* 10 msec */
5498e1e1df2SByungchul Park MARK(1000000ULL , '#'), /* 1000 usecs */
5508e1e1df2SByungchul Park MARK(100000ULL , '!'), /* 100 usecs */
5518e1e1df2SByungchul Park MARK(10000ULL , '+'), /* 10 usecs */
5528e1e1df2SByungchul Park };
5538e1e1df2SByungchul Park #undef MARK
5548e1e1df2SByungchul Park
trace_find_mark(unsigned long long d)5558e1e1df2SByungchul Park char trace_find_mark(unsigned long long d)
5568e1e1df2SByungchul Park {
5578e1e1df2SByungchul Park int i;
5588e1e1df2SByungchul Park int size = ARRAY_SIZE(mark);
5598e1e1df2SByungchul Park
5608e1e1df2SByungchul Park for (i = 0; i < size; i++) {
561b838e1d9SJungseok Lee if (d > mark[i].val)
5628e1e1df2SByungchul Park break;
5638e1e1df2SByungchul Park }
5648e1e1df2SByungchul Park
5658e1e1df2SByungchul Park return (i == size) ? ' ' : mark[i].sym;
5668e1e1df2SByungchul Park }
567c4a8e8beSFrederic Weisbecker
568d9793bd8SArnaldo Carvalho de Melo static int
lat_print_timestamp(struct trace_iterator * iter,u64 next_ts)5698be0709fSDavid Sharp lat_print_timestamp(struct trace_iterator *iter, u64 next_ts)
570c4a8e8beSFrederic Weisbecker {
571983f938aSSteven Rostedt (Red Hat) struct trace_array *tr = iter->tr;
572983f938aSSteven Rostedt (Red Hat) unsigned long verbose = tr->trace_flags & TRACE_ITER_VERBOSE;
5738be0709fSDavid Sharp unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS;
5741c5eb448SSteven Rostedt (VMware) unsigned long long abs_ts = iter->ts - iter->array_buffer->time_start;
5758be0709fSDavid Sharp unsigned long long rel_ts = next_ts - iter->ts;
5768be0709fSDavid Sharp struct trace_seq *s = &iter->seq;
5778be0709fSDavid Sharp
5788be0709fSDavid Sharp if (in_ns) {
5798be0709fSDavid Sharp abs_ts = ns2usecs(abs_ts);
5808be0709fSDavid Sharp rel_ts = ns2usecs(rel_ts);
5818be0709fSDavid Sharp }
5828be0709fSDavid Sharp
5838be0709fSDavid Sharp if (verbose && in_ns) {
5848be0709fSDavid Sharp unsigned long abs_usec = do_div(abs_ts, USEC_PER_MSEC);
5858be0709fSDavid Sharp unsigned long abs_msec = (unsigned long)abs_ts;
5868be0709fSDavid Sharp unsigned long rel_usec = do_div(rel_ts, USEC_PER_MSEC);
5878be0709fSDavid Sharp unsigned long rel_msec = (unsigned long)rel_ts;
5888be0709fSDavid Sharp
58919a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(
5908be0709fSDavid Sharp s, "[%08llx] %ld.%03ldms (+%ld.%03ldms): ",
5918be0709fSDavid Sharp ns2usecs(iter->ts),
5928be0709fSDavid Sharp abs_msec, abs_usec,
5938be0709fSDavid Sharp rel_msec, rel_usec);
59419a7fe20SSteven Rostedt (Red Hat)
5958be0709fSDavid Sharp } else if (verbose && !in_ns) {
59619a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(
5978be0709fSDavid Sharp s, "[%016llx] %lld (+%lld): ",
5988be0709fSDavid Sharp iter->ts, abs_ts, rel_ts);
59919a7fe20SSteven Rostedt (Red Hat)
6008be0709fSDavid Sharp } else if (!verbose && in_ns) {
60119a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(
6028be0709fSDavid Sharp s, " %4lldus%c: ",
6038be0709fSDavid Sharp abs_ts,
6048e1e1df2SByungchul Park trace_find_mark(rel_ts * NSEC_PER_USEC));
60519a7fe20SSteven Rostedt (Red Hat)
6068be0709fSDavid Sharp } else { /* !verbose && !in_ns */
60719a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, " %4lld: ", abs_ts);
6088be0709fSDavid Sharp }
60919a7fe20SSteven Rostedt (Red Hat)
61019a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
611c4a8e8beSFrederic Weisbecker }
612c4a8e8beSFrederic Weisbecker
trace_print_time(struct trace_seq * s,struct trace_iterator * iter,unsigned long long ts)613eaa7a897SYordan Karadzhov (VMware) static void trace_print_time(struct trace_seq *s, struct trace_iterator *iter,
614eaa7a897SYordan Karadzhov (VMware) unsigned long long ts)
615eaa7a897SYordan Karadzhov (VMware) {
616eaa7a897SYordan Karadzhov (VMware) unsigned long secs, usec_rem;
617eaa7a897SYordan Karadzhov (VMware) unsigned long long t;
618eaa7a897SYordan Karadzhov (VMware)
619eaa7a897SYordan Karadzhov (VMware) if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) {
620eaa7a897SYordan Karadzhov (VMware) t = ns2usecs(ts);
621eaa7a897SYordan Karadzhov (VMware) usec_rem = do_div(t, USEC_PER_SEC);
622eaa7a897SYordan Karadzhov (VMware) secs = (unsigned long)t;
623eaa7a897SYordan Karadzhov (VMware) trace_seq_printf(s, " %5lu.%06lu", secs, usec_rem);
624eaa7a897SYordan Karadzhov (VMware) } else
625eaa7a897SYordan Karadzhov (VMware) trace_seq_printf(s, " %12llu", ts);
626eaa7a897SYordan Karadzhov (VMware) }
627eaa7a897SYordan Karadzhov (VMware)
trace_print_context(struct trace_iterator * iter)628c4a8e8beSFrederic Weisbecker int trace_print_context(struct trace_iterator *iter)
629c4a8e8beSFrederic Weisbecker {
630983f938aSSteven Rostedt (Red Hat) struct trace_array *tr = iter->tr;
631c4a8e8beSFrederic Weisbecker struct trace_seq *s = &iter->seq;
632c4a8e8beSFrederic Weisbecker struct trace_entry *entry = iter->ent;
6334ca53085SSteven Rostedt char comm[TASK_COMM_LEN];
6344ca53085SSteven Rostedt
6354ca53085SSteven Rostedt trace_find_cmdline(entry->pid, comm);
636c4a8e8beSFrederic Weisbecker
637795d6379SSebastian Andrzej Siewior trace_seq_printf(s, "%16s-%-7d ", comm, entry->pid);
63877271ce4SSteven Rostedt
639441dae8fSJoel Fernandes if (tr->trace_flags & TRACE_ITER_RECORD_TGID) {
640441dae8fSJoel Fernandes unsigned int tgid = trace_find_tgid(entry->pid);
641441dae8fSJoel Fernandes
642441dae8fSJoel Fernandes if (!tgid)
643795d6379SSebastian Andrzej Siewior trace_seq_printf(s, "(-------) ");
644441dae8fSJoel Fernandes else
645795d6379SSebastian Andrzej Siewior trace_seq_printf(s, "(%7d) ", tgid);
646441dae8fSJoel Fernandes }
647441dae8fSJoel Fernandes
648f8494fa3SJoel Fernandes (Google) trace_seq_printf(s, "[%03d] ", iter->cpu);
649f8494fa3SJoel Fernandes (Google)
650983f938aSSteven Rostedt (Red Hat) if (tr->trace_flags & TRACE_ITER_IRQ_INFO)
65119a7fe20SSteven Rostedt (Red Hat) trace_print_lat_fmt(s, entry);
65277271ce4SSteven Rostedt
653eaa7a897SYordan Karadzhov (VMware) trace_print_time(s, iter, iter->ts);
654eaa7a897SYordan Karadzhov (VMware) trace_seq_puts(s, ": ");
65519a7fe20SSteven Rostedt (Red Hat)
65619a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
657c4a8e8beSFrederic Weisbecker }
658c4a8e8beSFrederic Weisbecker
trace_print_lat_context(struct trace_iterator * iter)659c4a8e8beSFrederic Weisbecker int trace_print_lat_context(struct trace_iterator *iter)
660c4a8e8beSFrederic Weisbecker {
661ff895103SSteven Rostedt (VMware) struct trace_entry *entry, *next_entry;
662983f938aSSteven Rostedt (Red Hat) struct trace_array *tr = iter->tr;
663c4a8e8beSFrederic Weisbecker struct trace_seq *s = &iter->seq;
664983f938aSSteven Rostedt (Red Hat) unsigned long verbose = (tr->trace_flags & TRACE_ITER_VERBOSE);
665ff895103SSteven Rostedt (VMware) u64 next_ts;
666c4a8e8beSFrederic Weisbecker
667ff895103SSteven Rostedt (VMware) next_entry = trace_find_next_entry(iter, NULL, &next_ts);
668c4a8e8beSFrederic Weisbecker if (!next_entry)
669c4a8e8beSFrederic Weisbecker next_ts = iter->ts;
670c4a8e8beSFrederic Weisbecker
671ff895103SSteven Rostedt (VMware) /* trace_find_next_entry() may change iter->ent */
672ff895103SSteven Rostedt (VMware) entry = iter->ent;
673ff895103SSteven Rostedt (VMware)
674c4a8e8beSFrederic Weisbecker if (verbose) {
6754ca53085SSteven Rostedt char comm[TASK_COMM_LEN];
6764ca53085SSteven Rostedt
6774ca53085SSteven Rostedt trace_find_cmdline(entry->pid, comm);
6784ca53085SSteven Rostedt
67919a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(
680795d6379SSebastian Andrzej Siewior s, "%16s %7d %3d %d %08x %08lx ",
6818be0709fSDavid Sharp comm, entry->pid, iter->cpu, entry->flags,
68254357f0cSThomas Gleixner entry->preempt_count & 0xf, iter->idx);
683c4a8e8beSFrederic Weisbecker } else {
68419a7fe20SSteven Rostedt (Red Hat) lat_print_generic(s, entry, iter->cpu);
685c4a8e8beSFrederic Weisbecker }
686c4a8e8beSFrederic Weisbecker
68719a7fe20SSteven Rostedt (Red Hat) lat_print_timestamp(iter, next_ts);
6888be0709fSDavid Sharp
68919a7fe20SSteven Rostedt (Red Hat) return !trace_seq_has_overflowed(s);
690c4a8e8beSFrederic Weisbecker }
691c4a8e8beSFrederic Weisbecker
692533c20b0SSven Schnelle #ifdef CONFIG_FUNCTION_TRACE_ARGS
print_function_args(struct trace_seq * s,unsigned long * args,unsigned long func)693533c20b0SSven Schnelle void print_function_args(struct trace_seq *s, unsigned long *args,
694533c20b0SSven Schnelle unsigned long func)
695533c20b0SSven Schnelle {
696533c20b0SSven Schnelle const struct btf_param *param;
697533c20b0SSven Schnelle const struct btf_type *t;
698533c20b0SSven Schnelle const char *param_name;
699533c20b0SSven Schnelle char name[KSYM_NAME_LEN];
700533c20b0SSven Schnelle unsigned long arg;
701533c20b0SSven Schnelle struct btf *btf;
702533c20b0SSven Schnelle s32 tid, nr = 0;
703533c20b0SSven Schnelle int a, p, x;
704533c20b0SSven Schnelle
705533c20b0SSven Schnelle trace_seq_printf(s, "(");
706533c20b0SSven Schnelle
707533c20b0SSven Schnelle if (!args)
708533c20b0SSven Schnelle goto out;
709533c20b0SSven Schnelle if (lookup_symbol_name(func, name))
710533c20b0SSven Schnelle goto out;
711533c20b0SSven Schnelle
712533c20b0SSven Schnelle /* TODO: Pass module name here too */
713533c20b0SSven Schnelle t = btf_find_func_proto(name, &btf);
714533c20b0SSven Schnelle if (IS_ERR_OR_NULL(t))
715533c20b0SSven Schnelle goto out;
716533c20b0SSven Schnelle
717533c20b0SSven Schnelle param = btf_get_func_param(t, &nr);
718533c20b0SSven Schnelle if (!param)
719533c20b0SSven Schnelle goto out_put;
720533c20b0SSven Schnelle
721533c20b0SSven Schnelle for (a = 0, p = 0; p < nr; a++, p++) {
722533c20b0SSven Schnelle if (p)
723533c20b0SSven Schnelle trace_seq_puts(s, ", ");
724533c20b0SSven Schnelle
725533c20b0SSven Schnelle /* This only prints what the arch allows (6 args by default) */
726533c20b0SSven Schnelle if (a == FTRACE_REGS_MAX_ARGS) {
727533c20b0SSven Schnelle trace_seq_puts(s, "...");
728533c20b0SSven Schnelle break;
729533c20b0SSven Schnelle }
730533c20b0SSven Schnelle
731533c20b0SSven Schnelle arg = args[a];
732533c20b0SSven Schnelle
733533c20b0SSven Schnelle param_name = btf_name_by_offset(btf, param[p].name_off);
734533c20b0SSven Schnelle if (param_name)
735533c20b0SSven Schnelle trace_seq_printf(s, "%s=", param_name);
736533c20b0SSven Schnelle t = btf_type_skip_modifiers(btf, param[p].type, &tid);
737533c20b0SSven Schnelle
738533c20b0SSven Schnelle switch (t ? BTF_INFO_KIND(t->info) : BTF_KIND_UNKN) {
739533c20b0SSven Schnelle case BTF_KIND_UNKN:
740533c20b0SSven Schnelle trace_seq_putc(s, '?');
741533c20b0SSven Schnelle /* Still print unknown type values */
742533c20b0SSven Schnelle fallthrough;
743533c20b0SSven Schnelle case BTF_KIND_PTR:
744533c20b0SSven Schnelle trace_seq_printf(s, "0x%lx", arg);
745533c20b0SSven Schnelle break;
746533c20b0SSven Schnelle case BTF_KIND_INT:
747533c20b0SSven Schnelle trace_seq_printf(s, "%ld", arg);
748533c20b0SSven Schnelle break;
749533c20b0SSven Schnelle case BTF_KIND_ENUM:
750533c20b0SSven Schnelle trace_seq_printf(s, "%ld", arg);
751533c20b0SSven Schnelle break;
752533c20b0SSven Schnelle default:
753533c20b0SSven Schnelle /* This does not handle complex arguments */
754533c20b0SSven Schnelle trace_seq_printf(s, "(%s)[0x%lx", btf_type_str(t), arg);
755533c20b0SSven Schnelle for (x = sizeof(long); x < t->size; x += sizeof(long)) {
756533c20b0SSven Schnelle trace_seq_putc(s, ':');
757533c20b0SSven Schnelle if (++a == FTRACE_REGS_MAX_ARGS) {
758533c20b0SSven Schnelle trace_seq_puts(s, "...]");
759533c20b0SSven Schnelle goto out_put;
760533c20b0SSven Schnelle }
761533c20b0SSven Schnelle trace_seq_printf(s, "0x%lx", args[a]);
762533c20b0SSven Schnelle }
763533c20b0SSven Schnelle trace_seq_putc(s, ']');
764533c20b0SSven Schnelle break;
765533c20b0SSven Schnelle }
766533c20b0SSven Schnelle }
767533c20b0SSven Schnelle out_put:
768533c20b0SSven Schnelle btf_put(btf);
769533c20b0SSven Schnelle out:
770533c20b0SSven Schnelle trace_seq_printf(s, ")");
771533c20b0SSven Schnelle }
772533c20b0SSven Schnelle #endif
773533c20b0SSven Schnelle
774f0868d1eSSteven Rostedt /**
775f0868d1eSSteven Rostedt * ftrace_find_event - find a registered event
776f0868d1eSSteven Rostedt * @type: the type of event to look for
777f0868d1eSSteven Rostedt *
778f0868d1eSSteven Rostedt * Returns an event of type @type otherwise NULL
7794f535968SLai Jiangshan * Called with trace_event_read_lock() held.
780f0868d1eSSteven Rostedt */
ftrace_find_event(int type)781f0868d1eSSteven Rostedt struct trace_event *ftrace_find_event(int type)
782f0868d1eSSteven Rostedt {
783f0868d1eSSteven Rostedt struct trace_event *event;
784f0868d1eSSteven Rostedt
785391dda1bSSasha Levin hash_for_each_possible(event_hash, event, node, type) {
786f0868d1eSSteven Rostedt if (event->type == type)
787f0868d1eSSteven Rostedt return event;
788f0868d1eSSteven Rostedt }
789f0868d1eSSteven Rostedt
790f0868d1eSSteven Rostedt return NULL;
791f0868d1eSSteven Rostedt }
792f0868d1eSSteven Rostedt
79396e6122cSZheng Yejian static DEFINE_IDA(trace_event_ida);
794060fa5c8SSteven Rostedt
free_trace_event_type(int type)79596e6122cSZheng Yejian static void free_trace_event_type(int type)
796060fa5c8SSteven Rostedt {
79796e6122cSZheng Yejian if (type >= __TRACE_LAST_TYPE)
79896e6122cSZheng Yejian ida_free(&trace_event_ida, type);
799060fa5c8SSteven Rostedt }
800060fa5c8SSteven Rostedt
alloc_trace_event_type(void)80196e6122cSZheng Yejian static int alloc_trace_event_type(void)
80296e6122cSZheng Yejian {
80396e6122cSZheng Yejian int next;
804060fa5c8SSteven Rostedt
80596e6122cSZheng Yejian /* Skip static defined type numbers */
80696e6122cSZheng Yejian next = ida_alloc_range(&trace_event_ida, __TRACE_LAST_TYPE,
80796e6122cSZheng Yejian TRACE_EVENT_TYPE_MAX, GFP_KERNEL);
80896e6122cSZheng Yejian if (next < 0)
809060fa5c8SSteven Rostedt return 0;
810746cf345SWei Yang return next;
811060fa5c8SSteven Rostedt }
812060fa5c8SSteven Rostedt
trace_event_read_lock(void)8134f535968SLai Jiangshan void trace_event_read_lock(void)
8144f535968SLai Jiangshan {
81552f6ad6dSzhangwei(Jovi) down_read(&trace_event_sem);
8164f535968SLai Jiangshan }
8174f535968SLai Jiangshan
trace_event_read_unlock(void)8184f535968SLai Jiangshan void trace_event_read_unlock(void)
8194f535968SLai Jiangshan {
82052f6ad6dSzhangwei(Jovi) up_read(&trace_event_sem);
8214f535968SLai Jiangshan }
8224f535968SLai Jiangshan
823f0868d1eSSteven Rostedt /**
8249023c930SSteven Rostedt (Red Hat) * register_trace_event - register output for an event type
825f0868d1eSSteven Rostedt * @event: the event type to register
826f0868d1eSSteven Rostedt *
827f0868d1eSSteven Rostedt * Event types are stored in a hash and this hash is used to
828f0868d1eSSteven Rostedt * find a way to print an event. If the @event->type is set
829f0868d1eSSteven Rostedt * then it will use that type, otherwise it will assign a
830f0868d1eSSteven Rostedt * type to use.
831f0868d1eSSteven Rostedt *
832f0868d1eSSteven Rostedt * If you assign your own type, please make sure it is added
833f0868d1eSSteven Rostedt * to the trace_type enum in trace.h, to avoid collisions
834f0868d1eSSteven Rostedt * with the dynamic types.
835f0868d1eSSteven Rostedt *
836f0868d1eSSteven Rostedt * Returns the event type number or zero on error.
837f0868d1eSSteven Rostedt */
register_trace_event(struct trace_event * event)8389023c930SSteven Rostedt (Red Hat) int register_trace_event(struct trace_event *event)
839f0868d1eSSteven Rostedt {
840f0868d1eSSteven Rostedt int ret = 0;
841f0868d1eSSteven Rostedt
84252f6ad6dSzhangwei(Jovi) down_write(&trace_event_sem);
843f0868d1eSSteven Rostedt
844060fa5c8SSteven Rostedt if (WARN_ON(!event))
84528bea271SPeter Zijlstra goto out;
846060fa5c8SSteven Rostedt
847a9a57763SSteven Rostedt if (WARN_ON(!event->funcs))
848a9a57763SSteven Rostedt goto out;
849a9a57763SSteven Rostedt
850060fa5c8SSteven Rostedt if (!event->type) {
85196e6122cSZheng Yejian event->type = alloc_trace_event_type();
852060fa5c8SSteven Rostedt if (!event->type)
853060fa5c8SSteven Rostedt goto out;
8544ee51101SGuo Zhengkui } else if (WARN(event->type > __TRACE_LAST_TYPE,
8554ee51101SGuo Zhengkui "Need to add type to trace.h")) {
856060fa5c8SSteven Rostedt goto out;
857060fa5c8SSteven Rostedt } else {
858060fa5c8SSteven Rostedt /* Is this event already used */
859f0868d1eSSteven Rostedt if (ftrace_find_event(event->type))
860f0868d1eSSteven Rostedt goto out;
861060fa5c8SSteven Rostedt }
862f0868d1eSSteven Rostedt
863a9a57763SSteven Rostedt if (event->funcs->trace == NULL)
864a9a57763SSteven Rostedt event->funcs->trace = trace_nop_print;
865a9a57763SSteven Rostedt if (event->funcs->raw == NULL)
866a9a57763SSteven Rostedt event->funcs->raw = trace_nop_print;
867a9a57763SSteven Rostedt if (event->funcs->hex == NULL)
868a9a57763SSteven Rostedt event->funcs->hex = trace_nop_print;
869a9a57763SSteven Rostedt if (event->funcs->binary == NULL)
870a9a57763SSteven Rostedt event->funcs->binary = trace_nop_print;
871268ccda0SArnaldo Carvalho de Melo
872391dda1bSSasha Levin hash_add(event_hash, &event->node, event->type);
873f0868d1eSSteven Rostedt
874f0868d1eSSteven Rostedt ret = event->type;
875f0868d1eSSteven Rostedt out:
87652f6ad6dSzhangwei(Jovi) up_write(&trace_event_sem);
877f0868d1eSSteven Rostedt
878f0868d1eSSteven Rostedt return ret;
879f0868d1eSSteven Rostedt }
8809023c930SSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(register_trace_event);
881f0868d1eSSteven Rostedt
882110bf2b7SSteven Rostedt /*
88352f6ad6dSzhangwei(Jovi) * Used by module code with the trace_event_sem held for write.
884110bf2b7SSteven Rostedt */
__unregister_trace_event(struct trace_event * event)8859023c930SSteven Rostedt (Red Hat) int __unregister_trace_event(struct trace_event *event)
886110bf2b7SSteven Rostedt {
887391dda1bSSasha Levin hash_del(&event->node);
88896e6122cSZheng Yejian free_trace_event_type(event->type);
889110bf2b7SSteven Rostedt return 0;
890110bf2b7SSteven Rostedt }
891110bf2b7SSteven Rostedt
892f0868d1eSSteven Rostedt /**
8939023c930SSteven Rostedt (Red Hat) * unregister_trace_event - remove a no longer used event
894f0868d1eSSteven Rostedt * @event: the event to remove
895f0868d1eSSteven Rostedt */
unregister_trace_event(struct trace_event * event)8969023c930SSteven Rostedt (Red Hat) int unregister_trace_event(struct trace_event *event)
897f0868d1eSSteven Rostedt {
89852f6ad6dSzhangwei(Jovi) down_write(&trace_event_sem);
8999023c930SSteven Rostedt (Red Hat) __unregister_trace_event(event);
90052f6ad6dSzhangwei(Jovi) up_write(&trace_event_sem);
901f0868d1eSSteven Rostedt
902f0868d1eSSteven Rostedt return 0;
903f0868d1eSSteven Rostedt }
9049023c930SSteven Rostedt (Red Hat) EXPORT_SYMBOL_GPL(unregister_trace_event);
905f633cef0SSteven Rostedt
906f633cef0SSteven Rostedt /*
907f633cef0SSteven Rostedt * Standard events
908f633cef0SSteven Rostedt */
909f633cef0SSteven Rostedt
print_array(struct trace_iterator * iter,void * pos,struct ftrace_event_field * field)91080a76994SSteven Rostedt (Google) static void print_array(struct trace_iterator *iter, void *pos,
91180a76994SSteven Rostedt (Google) struct ftrace_event_field *field)
91280a76994SSteven Rostedt (Google) {
91380a76994SSteven Rostedt (Google) int offset;
91480a76994SSteven Rostedt (Google) int len;
91580a76994SSteven Rostedt (Google) int i;
91680a76994SSteven Rostedt (Google)
91780a76994SSteven Rostedt (Google) offset = *(int *)pos & 0xffff;
91880a76994SSteven Rostedt (Google) len = *(int *)pos >> 16;
91980a76994SSteven Rostedt (Google)
92080a76994SSteven Rostedt (Google) if (field)
921c7bdb079SBeau Belgrave offset += field->offset + sizeof(int);
92280a76994SSteven Rostedt (Google)
923c7bdb079SBeau Belgrave if (offset + len > iter->ent_size) {
92480a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<OVERFLOW>");
92580a76994SSteven Rostedt (Google) return;
92680a76994SSteven Rostedt (Google) }
92780a76994SSteven Rostedt (Google)
928c7bdb079SBeau Belgrave pos = (void *)iter->ent + offset;
929c7bdb079SBeau Belgrave
93080a76994SSteven Rostedt (Google) for (i = 0; i < len; i++, pos++) {
93180a76994SSteven Rostedt (Google) if (i)
93280a76994SSteven Rostedt (Google) trace_seq_putc(&iter->seq, ',');
93380a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%02x", *(unsigned char *)pos);
93480a76994SSteven Rostedt (Google) }
93580a76994SSteven Rostedt (Google) }
93680a76994SSteven Rostedt (Google)
print_fields(struct trace_iterator * iter,struct trace_event_call * call,struct list_head * head)93780a76994SSteven Rostedt (Google) static void print_fields(struct trace_iterator *iter, struct trace_event_call *call,
93880a76994SSteven Rostedt (Google) struct list_head *head)
93980a76994SSteven Rostedt (Google) {
94080a76994SSteven Rostedt (Google) struct ftrace_event_field *field;
94180a76994SSteven Rostedt (Google) int offset;
94280a76994SSteven Rostedt (Google) int len;
94380a76994SSteven Rostedt (Google) int ret;
94480a76994SSteven Rostedt (Google) void *pos;
94580a76994SSteven Rostedt (Google)
946e70bb54dSsunliming list_for_each_entry_reverse(field, head, link) {
94780a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, " %s=", field->name);
94880a76994SSteven Rostedt (Google) if (field->offset + field->size > iter->ent_size) {
94980a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<OVERFLOW>");
95080a76994SSteven Rostedt (Google) continue;
95180a76994SSteven Rostedt (Google) }
95280a76994SSteven Rostedt (Google) pos = (void *)iter->ent + field->offset;
95380a76994SSteven Rostedt (Google)
95480a76994SSteven Rostedt (Google) switch (field->filter_type) {
95580a76994SSteven Rostedt (Google) case FILTER_COMM:
95680a76994SSteven Rostedt (Google) case FILTER_STATIC_STRING:
95780a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%.*s", field->size, (char *)pos);
95880a76994SSteven Rostedt (Google) break;
95980a76994SSteven Rostedt (Google) case FILTER_RDYN_STRING:
96080a76994SSteven Rostedt (Google) case FILTER_DYN_STRING:
96180a76994SSteven Rostedt (Google) offset = *(int *)pos & 0xffff;
96280a76994SSteven Rostedt (Google) len = *(int *)pos >> 16;
96380a76994SSteven Rostedt (Google)
96480a76994SSteven Rostedt (Google) if (field->filter_type == FILTER_RDYN_STRING)
965c7bdb079SBeau Belgrave offset += field->offset + sizeof(int);
96680a76994SSteven Rostedt (Google)
967c7bdb079SBeau Belgrave if (offset + len > iter->ent_size) {
96880a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<OVERFLOW>");
96980a76994SSteven Rostedt (Google) break;
97080a76994SSteven Rostedt (Google) }
97180a76994SSteven Rostedt (Google) pos = (void *)iter->ent + offset;
97280a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%.*s", len, (char *)pos);
97380a76994SSteven Rostedt (Google) break;
97480a76994SSteven Rostedt (Google) case FILTER_PTR_STRING:
97580a76994SSteven Rostedt (Google) if (!iter->fmt_size)
97680a76994SSteven Rostedt (Google) trace_iter_expand_format(iter);
97780a76994SSteven Rostedt (Google) pos = *(void **)pos;
97880a76994SSteven Rostedt (Google) ret = strncpy_from_kernel_nofault(iter->fmt, pos,
97980a76994SSteven Rostedt (Google) iter->fmt_size);
98080a76994SSteven Rostedt (Google) if (ret < 0)
98180a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "(0x%px)", pos);
98280a76994SSteven Rostedt (Google) else
98380a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "(0x%px:%s)",
98480a76994SSteven Rostedt (Google) pos, iter->fmt);
98580a76994SSteven Rostedt (Google) break;
98680a76994SSteven Rostedt (Google) case FILTER_TRACE_FN:
98780a76994SSteven Rostedt (Google) pos = *(void **)pos;
98880a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%pS", pos);
98980a76994SSteven Rostedt (Google) break;
99080a76994SSteven Rostedt (Google) case FILTER_CPU:
99180a76994SSteven Rostedt (Google) case FILTER_OTHER:
99280a76994SSteven Rostedt (Google) switch (field->size) {
99380a76994SSteven Rostedt (Google) case 1:
99480a76994SSteven Rostedt (Google) if (isprint(*(char *)pos)) {
99580a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "'%c'",
99680a76994SSteven Rostedt (Google) *(unsigned char *)pos);
99780a76994SSteven Rostedt (Google) }
99880a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "(%d)",
99980a76994SSteven Rostedt (Google) *(unsigned char *)pos);
100080a76994SSteven Rostedt (Google) break;
100180a76994SSteven Rostedt (Google) case 2:
100280a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "0x%x (%d)",
100380a76994SSteven Rostedt (Google) *(unsigned short *)pos,
100480a76994SSteven Rostedt (Google) *(unsigned short *)pos);
100580a76994SSteven Rostedt (Google) break;
100680a76994SSteven Rostedt (Google) case 4:
100780a76994SSteven Rostedt (Google) /* dynamic array info is 4 bytes */
100880a76994SSteven Rostedt (Google) if (strstr(field->type, "__data_loc")) {
100980a76994SSteven Rostedt (Google) print_array(iter, pos, NULL);
101080a76994SSteven Rostedt (Google) break;
101180a76994SSteven Rostedt (Google) }
101280a76994SSteven Rostedt (Google)
101380a76994SSteven Rostedt (Google) if (strstr(field->type, "__rel_loc")) {
101480a76994SSteven Rostedt (Google) print_array(iter, pos, field);
101580a76994SSteven Rostedt (Google) break;
101680a76994SSteven Rostedt (Google) }
101780a76994SSteven Rostedt (Google)
101880a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "0x%x (%d)",
101980a76994SSteven Rostedt (Google) *(unsigned int *)pos,
102080a76994SSteven Rostedt (Google) *(unsigned int *)pos);
102180a76994SSteven Rostedt (Google) break;
102280a76994SSteven Rostedt (Google) case 8:
102380a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "0x%llx (%lld)",
102480a76994SSteven Rostedt (Google) *(unsigned long long *)pos,
102580a76994SSteven Rostedt (Google) *(unsigned long long *)pos);
102680a76994SSteven Rostedt (Google) break;
102780a76994SSteven Rostedt (Google) default:
102880a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<INVALID-SIZE>");
102980a76994SSteven Rostedt (Google) break;
103080a76994SSteven Rostedt (Google) }
103180a76994SSteven Rostedt (Google) break;
103280a76994SSteven Rostedt (Google) default:
103380a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "<INVALID-TYPE>");
103480a76994SSteven Rostedt (Google) }
103580a76994SSteven Rostedt (Google) }
103680a76994SSteven Rostedt (Google) trace_seq_putc(&iter->seq, '\n');
103780a76994SSteven Rostedt (Google) }
103880a76994SSteven Rostedt (Google)
print_event_fields(struct trace_iterator * iter,struct trace_event * event)103980a76994SSteven Rostedt (Google) enum print_line_t print_event_fields(struct trace_iterator *iter,
104080a76994SSteven Rostedt (Google) struct trace_event *event)
104180a76994SSteven Rostedt (Google) {
104280a76994SSteven Rostedt (Google) struct trace_event_call *call;
104380a76994SSteven Rostedt (Google) struct list_head *head;
104480a76994SSteven Rostedt (Google)
1045*0a8f11f8SSteven Rostedt lockdep_assert_held_read(&trace_event_sem);
1046*0a8f11f8SSteven Rostedt
104780a76994SSteven Rostedt (Google) /* ftrace defined events have separate call structures */
104880a76994SSteven Rostedt (Google) if (event->type <= __TRACE_LAST_TYPE) {
104980a76994SSteven Rostedt (Google) bool found = false;
105080a76994SSteven Rostedt (Google)
105180a76994SSteven Rostedt (Google) list_for_each_entry(call, &ftrace_events, list) {
105280a76994SSteven Rostedt (Google) if (call->event.type == event->type) {
105380a76994SSteven Rostedt (Google) found = true;
105480a76994SSteven Rostedt (Google) break;
105580a76994SSteven Rostedt (Google) }
105680a76994SSteven Rostedt (Google) /* No need to search all events */
105780a76994SSteven Rostedt (Google) if (call->event.type > __TRACE_LAST_TYPE)
105880a76994SSteven Rostedt (Google) break;
105980a76994SSteven Rostedt (Google) }
106080a76994SSteven Rostedt (Google) if (!found) {
106180a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "UNKNOWN TYPE %d\n", event->type);
106280a76994SSteven Rostedt (Google) goto out;
106380a76994SSteven Rostedt (Google) }
106480a76994SSteven Rostedt (Google) } else {
106580a76994SSteven Rostedt (Google) call = container_of(event, struct trace_event_call, event);
106680a76994SSteven Rostedt (Google) }
106780a76994SSteven Rostedt (Google) head = trace_get_fields(call);
106880a76994SSteven Rostedt (Google)
106980a76994SSteven Rostedt (Google) trace_seq_printf(&iter->seq, "%s:", trace_event_name(call));
107080a76994SSteven Rostedt (Google)
107180a76994SSteven Rostedt (Google) if (head && !list_empty(head))
107280a76994SSteven Rostedt (Google) print_fields(iter, call, head);
107380a76994SSteven Rostedt (Google) else
107480a76994SSteven Rostedt (Google) trace_seq_puts(&iter->seq, "No fields found\n");
107580a76994SSteven Rostedt (Google)
107680a76994SSteven Rostedt (Google) out:
107780a76994SSteven Rostedt (Google) return trace_handle_return(&iter->seq);
107880a76994SSteven Rostedt (Google) }
107980a76994SSteven Rostedt (Google)
trace_nop_print(struct trace_iterator * iter,int flags,struct trace_event * event)1080a9a57763SSteven Rostedt enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags,
1081a9a57763SSteven Rostedt struct trace_event *event)
1082f633cef0SSteven Rostedt {
108319a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(&iter->seq, "type: %d\n", iter->ent->type);
1084ee5e51f5SJiri Olsa
108519a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
1086f633cef0SSteven Rostedt }
1087f633cef0SSteven Rostedt
print_fn_trace(struct trace_seq * s,unsigned long ip,unsigned long parent_ip,long delta,unsigned long * args,int flags)1088e1db6338SSteven Rostedt (VMware) static void print_fn_trace(struct trace_seq *s, unsigned long ip,
108976fe0337SSven Schnelle unsigned long parent_ip, long delta,
109076fe0337SSven Schnelle unsigned long *args, int flags)
1091e1db6338SSteven Rostedt (VMware) {
10927cfeb903SSteven Rostedt (Google) ip += delta;
10937cfeb903SSteven Rostedt (Google) parent_ip += delta;
10947cfeb903SSteven Rostedt (Google)
1095e1db6338SSteven Rostedt (VMware) seq_print_ip_sym(s, ip, flags);
109676fe0337SSven Schnelle if (args)
109776fe0337SSven Schnelle print_function_args(s, args, ip);
1098e1db6338SSteven Rostedt (VMware)
1099e1db6338SSteven Rostedt (VMware) if ((flags & TRACE_ITER_PRINT_PARENT) && parent_ip) {
1100e1db6338SSteven Rostedt (VMware) trace_seq_puts(s, " <-");
1101e1db6338SSteven Rostedt (VMware) seq_print_ip_sym(s, parent_ip, flags);
1102e1db6338SSteven Rostedt (VMware) }
1103e1db6338SSteven Rostedt (VMware) }
1104e1db6338SSteven Rostedt (VMware)
1105f633cef0SSteven Rostedt /* TRACE_FN */
trace_fn_trace(struct trace_iterator * iter,int flags,struct trace_event * event)1106a9a57763SSteven Rostedt static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags,
1107a9a57763SSteven Rostedt struct trace_event *event)
1108f633cef0SSteven Rostedt {
1109f633cef0SSteven Rostedt struct ftrace_entry *field;
11102c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
111176fe0337SSven Schnelle unsigned long *args;
111276fe0337SSven Schnelle int args_size;
1113f633cef0SSteven Rostedt
11142c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1115f633cef0SSteven Rostedt
111676fe0337SSven Schnelle args_size = iter->ent_size - offsetof(struct ftrace_entry, args);
111776fe0337SSven Schnelle if (args_size >= FTRACE_REGS_MAX_ARGS * sizeof(long))
111876fe0337SSven Schnelle args = field->args;
111976fe0337SSven Schnelle else
112076fe0337SSven Schnelle args = NULL;
112176fe0337SSven Schnelle
112276fe0337SSven Schnelle print_fn_trace(s, field->ip, field->parent_ip, iter->tr->text_delta,
112376fe0337SSven Schnelle args, flags);
112419a7fe20SSteven Rostedt (Red Hat) trace_seq_putc(s, '\n');
1125f633cef0SSteven Rostedt
112619a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1127f633cef0SSteven Rostedt }
1128f633cef0SSteven Rostedt
trace_fn_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1129a9a57763SSteven Rostedt static enum print_line_t trace_fn_raw(struct trace_iterator *iter, int flags,
1130a9a57763SSteven Rostedt struct trace_event *event)
1131f633cef0SSteven Rostedt {
1132f633cef0SSteven Rostedt struct ftrace_entry *field;
1133f633cef0SSteven Rostedt
11342c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1135f633cef0SSteven Rostedt
113619a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(&iter->seq, "%lx %lx\n",
1137f633cef0SSteven Rostedt field->ip,
113819a7fe20SSteven Rostedt (Red Hat) field->parent_ip);
1139f633cef0SSteven Rostedt
114019a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
1141f633cef0SSteven Rostedt }
1142f633cef0SSteven Rostedt
trace_fn_hex(struct trace_iterator * iter,int flags,struct trace_event * event)1143a9a57763SSteven Rostedt static enum print_line_t trace_fn_hex(struct trace_iterator *iter, int flags,
1144a9a57763SSteven Rostedt struct trace_event *event)
1145f633cef0SSteven Rostedt {
1146f633cef0SSteven Rostedt struct ftrace_entry *field;
11472c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1148f633cef0SSteven Rostedt
11492c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1150f633cef0SSteven Rostedt
115119a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->ip);
115219a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->parent_ip);
1153f633cef0SSteven Rostedt
115419a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1155f633cef0SSteven Rostedt }
1156f633cef0SSteven Rostedt
trace_fn_bin(struct trace_iterator * iter,int flags,struct trace_event * event)1157a9a57763SSteven Rostedt static enum print_line_t trace_fn_bin(struct trace_iterator *iter, int flags,
1158a9a57763SSteven Rostedt struct trace_event *event)
1159f633cef0SSteven Rostedt {
1160f633cef0SSteven Rostedt struct ftrace_entry *field;
11612c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1162f633cef0SSteven Rostedt
11632c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1164f633cef0SSteven Rostedt
116519a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->ip);
116619a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->parent_ip);
1167f633cef0SSteven Rostedt
116819a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1169f633cef0SSteven Rostedt }
1170f633cef0SSteven Rostedt
1171a9a57763SSteven Rostedt static struct trace_event_functions trace_fn_funcs = {
1172f633cef0SSteven Rostedt .trace = trace_fn_trace,
1173f633cef0SSteven Rostedt .raw = trace_fn_raw,
1174f633cef0SSteven Rostedt .hex = trace_fn_hex,
1175f633cef0SSteven Rostedt .binary = trace_fn_bin,
1176f633cef0SSteven Rostedt };
1177f633cef0SSteven Rostedt
1178a9a57763SSteven Rostedt static struct trace_event trace_fn_event = {
1179a9a57763SSteven Rostedt .type = TRACE_FN,
1180a9a57763SSteven Rostedt .funcs = &trace_fn_funcs,
1181a9a57763SSteven Rostedt };
1182a9a57763SSteven Rostedt
1183f633cef0SSteven Rostedt /* TRACE_CTX an TRACE_WAKE */
trace_ctxwake_print(struct trace_iterator * iter,char * delim)1184ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
1185ae7462b4SArnaldo Carvalho de Melo char *delim)
1186f633cef0SSteven Rostedt {
1187f633cef0SSteven Rostedt struct ctx_switch_entry *field;
11884ca53085SSteven Rostedt char comm[TASK_COMM_LEN];
1189f633cef0SSteven Rostedt int S, T;
1190f633cef0SSteven Rostedt
11914ca53085SSteven Rostedt
11922c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1193f633cef0SSteven Rostedt
11941d48b080SPeter Zijlstra T = task_index_to_char(field->next_state);
11951d48b080SPeter Zijlstra S = task_index_to_char(field->prev_state);
11964ca53085SSteven Rostedt trace_find_cmdline(field->next_pid, comm);
119719a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(&iter->seq,
1198795d6379SSebastian Andrzej Siewior " %7d:%3d:%c %s [%03d] %7d:%3d:%c %s\n",
1199f633cef0SSteven Rostedt field->prev_pid,
1200f633cef0SSteven Rostedt field->prev_prio,
1201f633cef0SSteven Rostedt S, delim,
1202f633cef0SSteven Rostedt field->next_cpu,
1203f633cef0SSteven Rostedt field->next_pid,
1204f633cef0SSteven Rostedt field->next_prio,
120519a7fe20SSteven Rostedt (Red Hat) T, comm);
1206f633cef0SSteven Rostedt
120719a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
1208f633cef0SSteven Rostedt }
1209f633cef0SSteven Rostedt
trace_ctx_print(struct trace_iterator * iter,int flags,struct trace_event * event)1210a9a57763SSteven Rostedt static enum print_line_t trace_ctx_print(struct trace_iterator *iter, int flags,
1211a9a57763SSteven Rostedt struct trace_event *event)
1212f633cef0SSteven Rostedt {
12132c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_print(iter, "==>");
1214f633cef0SSteven Rostedt }
1215f633cef0SSteven Rostedt
trace_wake_print(struct trace_iterator * iter,int flags,struct trace_event * event)1216ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_wake_print(struct trace_iterator *iter,
1217a9a57763SSteven Rostedt int flags, struct trace_event *event)
1218f633cef0SSteven Rostedt {
12192c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_print(iter, " +");
1220f633cef0SSteven Rostedt }
1221f633cef0SSteven Rostedt
trace_ctxwake_raw(struct trace_iterator * iter,char S)12222c9b238eSArnaldo Carvalho de Melo static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
1223f633cef0SSteven Rostedt {
1224f633cef0SSteven Rostedt struct ctx_switch_entry *field;
1225f633cef0SSteven Rostedt int T;
1226f633cef0SSteven Rostedt
12272c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1228f633cef0SSteven Rostedt
1229f633cef0SSteven Rostedt if (!S)
12301d48b080SPeter Zijlstra S = task_index_to_char(field->prev_state);
12311d48b080SPeter Zijlstra T = task_index_to_char(field->next_state);
123219a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
1233f633cef0SSteven Rostedt field->prev_pid,
1234f633cef0SSteven Rostedt field->prev_prio,
1235f633cef0SSteven Rostedt S,
1236f633cef0SSteven Rostedt field->next_cpu,
1237f633cef0SSteven Rostedt field->next_pid,
1238f633cef0SSteven Rostedt field->next_prio,
123919a7fe20SSteven Rostedt (Red Hat) T);
1240f633cef0SSteven Rostedt
124119a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
1242f633cef0SSteven Rostedt }
1243f633cef0SSteven Rostedt
trace_ctx_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1244a9a57763SSteven Rostedt static enum print_line_t trace_ctx_raw(struct trace_iterator *iter, int flags,
1245a9a57763SSteven Rostedt struct trace_event *event)
1246f633cef0SSteven Rostedt {
12472c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_raw(iter, 0);
1248f633cef0SSteven Rostedt }
1249f633cef0SSteven Rostedt
trace_wake_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1250a9a57763SSteven Rostedt static enum print_line_t trace_wake_raw(struct trace_iterator *iter, int flags,
1251a9a57763SSteven Rostedt struct trace_event *event)
1252f633cef0SSteven Rostedt {
12532c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_raw(iter, '+');
1254f633cef0SSteven Rostedt }
1255f633cef0SSteven Rostedt
1256f633cef0SSteven Rostedt
trace_ctxwake_hex(struct trace_iterator * iter,char S)12572c9b238eSArnaldo Carvalho de Melo static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
1258f633cef0SSteven Rostedt {
1259f633cef0SSteven Rostedt struct ctx_switch_entry *field;
12602c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1261f633cef0SSteven Rostedt int T;
1262f633cef0SSteven Rostedt
12632c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1264f633cef0SSteven Rostedt
1265f633cef0SSteven Rostedt if (!S)
12661d48b080SPeter Zijlstra S = task_index_to_char(field->prev_state);
12671d48b080SPeter Zijlstra T = task_index_to_char(field->next_state);
1268f633cef0SSteven Rostedt
126919a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->prev_pid);
127019a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->prev_prio);
127119a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, S);
127219a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->next_cpu);
127319a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->next_pid);
127419a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, field->next_prio);
127519a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_HEX_FIELD(s, T);
1276f633cef0SSteven Rostedt
127719a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1278f633cef0SSteven Rostedt }
1279f633cef0SSteven Rostedt
trace_ctx_hex(struct trace_iterator * iter,int flags,struct trace_event * event)1280a9a57763SSteven Rostedt static enum print_line_t trace_ctx_hex(struct trace_iterator *iter, int flags,
1281a9a57763SSteven Rostedt struct trace_event *event)
1282f633cef0SSteven Rostedt {
12832c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_hex(iter, 0);
1284f633cef0SSteven Rostedt }
1285f633cef0SSteven Rostedt
trace_wake_hex(struct trace_iterator * iter,int flags,struct trace_event * event)1286a9a57763SSteven Rostedt static enum print_line_t trace_wake_hex(struct trace_iterator *iter, int flags,
1287a9a57763SSteven Rostedt struct trace_event *event)
1288f633cef0SSteven Rostedt {
12892c9b238eSArnaldo Carvalho de Melo return trace_ctxwake_hex(iter, '+');
1290f633cef0SSteven Rostedt }
1291f633cef0SSteven Rostedt
trace_ctxwake_bin(struct trace_iterator * iter,int flags,struct trace_event * event)1292ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_ctxwake_bin(struct trace_iterator *iter,
1293a9a57763SSteven Rostedt int flags, struct trace_event *event)
1294f633cef0SSteven Rostedt {
1295f633cef0SSteven Rostedt struct ctx_switch_entry *field;
12962c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
1297f633cef0SSteven Rostedt
12982c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1299f633cef0SSteven Rostedt
130019a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->prev_pid);
130119a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->prev_prio);
130219a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->prev_state);
130319a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->next_cpu);
130419a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->next_pid);
130519a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->next_prio);
130619a7fe20SSteven Rostedt (Red Hat) SEQ_PUT_FIELD(s, field->next_state);
1307f633cef0SSteven Rostedt
130819a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1309f633cef0SSteven Rostedt }
1310f633cef0SSteven Rostedt
1311a9a57763SSteven Rostedt static struct trace_event_functions trace_ctx_funcs = {
1312f633cef0SSteven Rostedt .trace = trace_ctx_print,
1313f633cef0SSteven Rostedt .raw = trace_ctx_raw,
1314f633cef0SSteven Rostedt .hex = trace_ctx_hex,
1315f633cef0SSteven Rostedt .binary = trace_ctxwake_bin,
1316f633cef0SSteven Rostedt };
1317f633cef0SSteven Rostedt
1318a9a57763SSteven Rostedt static struct trace_event trace_ctx_event = {
1319a9a57763SSteven Rostedt .type = TRACE_CTX,
1320a9a57763SSteven Rostedt .funcs = &trace_ctx_funcs,
1321a9a57763SSteven Rostedt };
1322a9a57763SSteven Rostedt
1323a9a57763SSteven Rostedt static struct trace_event_functions trace_wake_funcs = {
1324f633cef0SSteven Rostedt .trace = trace_wake_print,
1325f633cef0SSteven Rostedt .raw = trace_wake_raw,
1326f633cef0SSteven Rostedt .hex = trace_wake_hex,
1327f633cef0SSteven Rostedt .binary = trace_ctxwake_bin,
1328f633cef0SSteven Rostedt };
1329f633cef0SSteven Rostedt
1330a9a57763SSteven Rostedt static struct trace_event trace_wake_event = {
1331a9a57763SSteven Rostedt .type = TRACE_WAKE,
1332a9a57763SSteven Rostedt .funcs = &trace_wake_funcs,
1333a9a57763SSteven Rostedt };
1334a9a57763SSteven Rostedt
1335f633cef0SSteven Rostedt /* TRACE_STACK */
1336f633cef0SSteven Rostedt
trace_stack_print(struct trace_iterator * iter,int flags,struct trace_event * event)1337ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_stack_print(struct trace_iterator *iter,
1338a9a57763SSteven Rostedt int flags, struct trace_event *event)
1339f633cef0SSteven Rostedt {
1340f633cef0SSteven Rostedt struct stack_entry *field;
13412c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
13424a9bd3f1SSteven Rostedt unsigned long *p;
13434a9bd3f1SSteven Rostedt unsigned long *end;
1344f633cef0SSteven Rostedt
13452c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
13464a9bd3f1SSteven Rostedt end = (unsigned long *)((long)iter->ent + iter->ent_size);
1347f633cef0SSteven Rostedt
134819a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, "<stack trace>\n");
13494a9bd3f1SSteven Rostedt
1350becf33f6SEiichi Tsukata for (p = field->caller; p && p < end && *p != ULONG_MAX; p++) {
1351f633cef0SSteven Rostedt
135219a7fe20SSteven Rostedt (Red Hat) if (trace_seq_has_overflowed(s))
135319a7fe20SSteven Rostedt (Red Hat) break;
135419a7fe20SSteven Rostedt (Red Hat)
135519a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, " => ");
13566ce5a6f0STatsuya S if ((*p) == FTRACE_TRAMPOLINE_MARKER) {
13576ce5a6f0STatsuya S trace_seq_puts(s, "[FTRACE TRAMPOLINE]\n");
13586ce5a6f0STatsuya S continue;
13596ce5a6f0STatsuya S }
136035a380ddSMasami Hiramatsu (Google) seq_print_ip_sym(s, trace_adjust_address(iter->tr, *p), flags);
136119a7fe20SSteven Rostedt (Red Hat) trace_seq_putc(s, '\n');
1362f633cef0SSteven Rostedt }
1363f633cef0SSteven Rostedt
136419a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1365f633cef0SSteven Rostedt }
1366f633cef0SSteven Rostedt
1367a9a57763SSteven Rostedt static struct trace_event_functions trace_stack_funcs = {
1368f633cef0SSteven Rostedt .trace = trace_stack_print,
1369f633cef0SSteven Rostedt };
1370f633cef0SSteven Rostedt
1371a9a57763SSteven Rostedt static struct trace_event trace_stack_event = {
1372a9a57763SSteven Rostedt .type = TRACE_STACK,
1373a9a57763SSteven Rostedt .funcs = &trace_stack_funcs,
1374a9a57763SSteven Rostedt };
1375a9a57763SSteven Rostedt
1376f633cef0SSteven Rostedt /* TRACE_USER_STACK */
trace_user_stack_print(struct trace_iterator * iter,int flags,struct trace_event * event)1377ae7462b4SArnaldo Carvalho de Melo static enum print_line_t trace_user_stack_print(struct trace_iterator *iter,
1378a9a57763SSteven Rostedt int flags, struct trace_event *event)
1379f633cef0SSteven Rostedt {
1380983f938aSSteven Rostedt (Red Hat) struct trace_array *tr = iter->tr;
1381f633cef0SSteven Rostedt struct userstack_entry *field;
13822c9b238eSArnaldo Carvalho de Melo struct trace_seq *s = &iter->seq;
13836b1032d5SSteven Rostedt (Red Hat) struct mm_struct *mm = NULL;
13846b1032d5SSteven Rostedt (Red Hat) unsigned int i;
1385f633cef0SSteven Rostedt
13862c9b238eSArnaldo Carvalho de Melo trace_assign_type(field, iter->ent);
1387f633cef0SSteven Rostedt
138819a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, "<user stack trace>\n");
13896b1032d5SSteven Rostedt (Red Hat)
1390983f938aSSteven Rostedt (Red Hat) if (tr->trace_flags & TRACE_ITER_SYM_USEROBJ) {
13916b1032d5SSteven Rostedt (Red Hat) struct task_struct *task;
13926b1032d5SSteven Rostedt (Red Hat) /*
13936b1032d5SSteven Rostedt (Red Hat) * we do the lookup on the thread group leader,
13946b1032d5SSteven Rostedt (Red Hat) * since individual threads might have already quit!
13956b1032d5SSteven Rostedt (Red Hat) */
13966b1032d5SSteven Rostedt (Red Hat) rcu_read_lock();
13976b1032d5SSteven Rostedt (Red Hat) task = find_task_by_vpid(field->tgid);
13986b1032d5SSteven Rostedt (Red Hat) if (task)
13996b1032d5SSteven Rostedt (Red Hat) mm = get_task_mm(task);
14006b1032d5SSteven Rostedt (Red Hat) rcu_read_unlock();
14016b1032d5SSteven Rostedt (Red Hat) }
14026b1032d5SSteven Rostedt (Red Hat)
14036b1032d5SSteven Rostedt (Red Hat) for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
14046b1032d5SSteven Rostedt (Red Hat) unsigned long ip = field->caller[i];
14056b1032d5SSteven Rostedt (Red Hat)
14066d54ceb5SEiichi Tsukata if (!ip || trace_seq_has_overflowed(s))
14076b1032d5SSteven Rostedt (Red Hat) break;
14086b1032d5SSteven Rostedt (Red Hat)
14096b1032d5SSteven Rostedt (Red Hat) trace_seq_puts(s, " => ");
14106b1032d5SSteven Rostedt (Red Hat) seq_print_user_ip(s, mm, ip, flags);
14116b1032d5SSteven Rostedt (Red Hat) trace_seq_putc(s, '\n');
14126b1032d5SSteven Rostedt (Red Hat) }
14136b1032d5SSteven Rostedt (Red Hat)
14146b1032d5SSteven Rostedt (Red Hat) if (mm)
14156b1032d5SSteven Rostedt (Red Hat) mmput(mm);
1416f633cef0SSteven Rostedt
141719a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
1418f633cef0SSteven Rostedt }
1419f633cef0SSteven Rostedt
1420a9a57763SSteven Rostedt static struct trace_event_functions trace_user_stack_funcs = {
1421f633cef0SSteven Rostedt .trace = trace_user_stack_print,
1422f633cef0SSteven Rostedt };
1423f633cef0SSteven Rostedt
1424a9a57763SSteven Rostedt static struct trace_event trace_user_stack_event = {
1425a9a57763SSteven Rostedt .type = TRACE_USER_STACK,
1426a9a57763SSteven Rostedt .funcs = &trace_user_stack_funcs,
1427a9a57763SSteven Rostedt };
1428a9a57763SSteven Rostedt
1429e7c15cd8SSteven Rostedt (Red Hat) /* TRACE_HWLAT */
1430e7c15cd8SSteven Rostedt (Red Hat) static enum print_line_t
trace_hwlat_print(struct trace_iterator * iter,int flags,struct trace_event * event)1431e7c15cd8SSteven Rostedt (Red Hat) trace_hwlat_print(struct trace_iterator *iter, int flags,
1432e7c15cd8SSteven Rostedt (Red Hat) struct trace_event *event)
1433e7c15cd8SSteven Rostedt (Red Hat) {
1434e7c15cd8SSteven Rostedt (Red Hat) struct trace_entry *entry = iter->ent;
1435e7c15cd8SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
1436e7c15cd8SSteven Rostedt (Red Hat) struct hwlat_entry *field;
1437e7c15cd8SSteven Rostedt (Red Hat)
1438e7c15cd8SSteven Rostedt (Red Hat) trace_assign_type(field, entry);
1439e7c15cd8SSteven Rostedt (Red Hat)
1440b396bfdeSSteven Rostedt (VMware) trace_seq_printf(s, "#%-5u inner/outer(us): %4llu/%-5llu ts:%lld.%09ld count:%d",
1441e7c15cd8SSteven Rostedt (Red Hat) field->seqnum,
1442e7c15cd8SSteven Rostedt (Red Hat) field->duration,
1443e7c15cd8SSteven Rostedt (Red Hat) field->outer_duration,
144451aad0aeSDeepa Dinamani (long long)field->timestamp.tv_sec,
1445b396bfdeSSteven Rostedt (VMware) field->timestamp.tv_nsec, field->count);
1446e7c15cd8SSteven Rostedt (Red Hat)
14477b2c8625SSteven Rostedt (Red Hat) if (field->nmi_count) {
14487b2c8625SSteven Rostedt (Red Hat) /*
14497b2c8625SSteven Rostedt (Red Hat) * The generic sched_clock() is not NMI safe, thus
14507b2c8625SSteven Rostedt (Red Hat) * we only record the count and not the time.
14517b2c8625SSteven Rostedt (Red Hat) */
14527b2c8625SSteven Rostedt (Red Hat) if (!IS_ENABLED(CONFIG_GENERIC_SCHED_CLOCK))
14537b2c8625SSteven Rostedt (Red Hat) trace_seq_printf(s, " nmi-total:%llu",
14547b2c8625SSteven Rostedt (Red Hat) field->nmi_total_ts);
14557b2c8625SSteven Rostedt (Red Hat) trace_seq_printf(s, " nmi-count:%u",
14567b2c8625SSteven Rostedt (Red Hat) field->nmi_count);
14577b2c8625SSteven Rostedt (Red Hat) }
14587b2c8625SSteven Rostedt (Red Hat)
14597b2c8625SSteven Rostedt (Red Hat) trace_seq_putc(s, '\n');
14607b2c8625SSteven Rostedt (Red Hat)
1461e7c15cd8SSteven Rostedt (Red Hat) return trace_handle_return(s);
1462e7c15cd8SSteven Rostedt (Red Hat) }
1463e7c15cd8SSteven Rostedt (Red Hat)
1464e7c15cd8SSteven Rostedt (Red Hat) static enum print_line_t
trace_hwlat_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1465e7c15cd8SSteven Rostedt (Red Hat) trace_hwlat_raw(struct trace_iterator *iter, int flags,
1466e7c15cd8SSteven Rostedt (Red Hat) struct trace_event *event)
1467e7c15cd8SSteven Rostedt (Red Hat) {
1468e7c15cd8SSteven Rostedt (Red Hat) struct hwlat_entry *field;
1469e7c15cd8SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
1470e7c15cd8SSteven Rostedt (Red Hat)
1471e7c15cd8SSteven Rostedt (Red Hat) trace_assign_type(field, iter->ent);
1472e7c15cd8SSteven Rostedt (Red Hat)
147351aad0aeSDeepa Dinamani trace_seq_printf(s, "%llu %lld %lld %09ld %u\n",
1474e7c15cd8SSteven Rostedt (Red Hat) field->duration,
1475e7c15cd8SSteven Rostedt (Red Hat) field->outer_duration,
147651aad0aeSDeepa Dinamani (long long)field->timestamp.tv_sec,
1477e7c15cd8SSteven Rostedt (Red Hat) field->timestamp.tv_nsec,
1478e7c15cd8SSteven Rostedt (Red Hat) field->seqnum);
1479e7c15cd8SSteven Rostedt (Red Hat)
1480e7c15cd8SSteven Rostedt (Red Hat) return trace_handle_return(s);
1481e7c15cd8SSteven Rostedt (Red Hat) }
1482e7c15cd8SSteven Rostedt (Red Hat)
1483e7c15cd8SSteven Rostedt (Red Hat) static struct trace_event_functions trace_hwlat_funcs = {
1484e7c15cd8SSteven Rostedt (Red Hat) .trace = trace_hwlat_print,
1485e7c15cd8SSteven Rostedt (Red Hat) .raw = trace_hwlat_raw,
1486e7c15cd8SSteven Rostedt (Red Hat) };
1487e7c15cd8SSteven Rostedt (Red Hat)
1488e7c15cd8SSteven Rostedt (Red Hat) static struct trace_event trace_hwlat_event = {
1489e7c15cd8SSteven Rostedt (Red Hat) .type = TRACE_HWLAT,
1490e7c15cd8SSteven Rostedt (Red Hat) .funcs = &trace_hwlat_funcs,
1491e7c15cd8SSteven Rostedt (Red Hat) };
1492e7c15cd8SSteven Rostedt (Red Hat)
1493bce29ac9SDaniel Bristot de Oliveira /* TRACE_OSNOISE */
1494bce29ac9SDaniel Bristot de Oliveira static enum print_line_t
trace_osnoise_print(struct trace_iterator * iter,int flags,struct trace_event * event)1495bce29ac9SDaniel Bristot de Oliveira trace_osnoise_print(struct trace_iterator *iter, int flags,
1496bce29ac9SDaniel Bristot de Oliveira struct trace_event *event)
1497bce29ac9SDaniel Bristot de Oliveira {
1498bce29ac9SDaniel Bristot de Oliveira struct trace_entry *entry = iter->ent;
1499bce29ac9SDaniel Bristot de Oliveira struct trace_seq *s = &iter->seq;
1500bce29ac9SDaniel Bristot de Oliveira struct osnoise_entry *field;
1501bce29ac9SDaniel Bristot de Oliveira u64 ratio, ratio_dec;
1502bce29ac9SDaniel Bristot de Oliveira u64 net_runtime;
1503bce29ac9SDaniel Bristot de Oliveira
1504bce29ac9SDaniel Bristot de Oliveira trace_assign_type(field, entry);
1505bce29ac9SDaniel Bristot de Oliveira
1506bce29ac9SDaniel Bristot de Oliveira /*
1507bce29ac9SDaniel Bristot de Oliveira * compute the available % of cpu time.
1508bce29ac9SDaniel Bristot de Oliveira */
1509bce29ac9SDaniel Bristot de Oliveira net_runtime = field->runtime - field->noise;
1510bce29ac9SDaniel Bristot de Oliveira ratio = net_runtime * 10000000;
1511bce29ac9SDaniel Bristot de Oliveira do_div(ratio, field->runtime);
1512bce29ac9SDaniel Bristot de Oliveira ratio_dec = do_div(ratio, 100000);
1513bce29ac9SDaniel Bristot de Oliveira
1514bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, "%llu %10llu %3llu.%05llu %7llu",
1515bce29ac9SDaniel Bristot de Oliveira field->runtime,
1516bce29ac9SDaniel Bristot de Oliveira field->noise,
1517bce29ac9SDaniel Bristot de Oliveira ratio, ratio_dec,
1518bce29ac9SDaniel Bristot de Oliveira field->max_sample);
1519bce29ac9SDaniel Bristot de Oliveira
1520bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->hw_count);
1521bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->nmi_count);
1522bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->irq_count);
1523bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->softirq_count);
1524bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, " %6u", field->thread_count);
1525bce29ac9SDaniel Bristot de Oliveira
1526bce29ac9SDaniel Bristot de Oliveira trace_seq_putc(s, '\n');
1527bce29ac9SDaniel Bristot de Oliveira
1528bce29ac9SDaniel Bristot de Oliveira return trace_handle_return(s);
1529bce29ac9SDaniel Bristot de Oliveira }
1530bce29ac9SDaniel Bristot de Oliveira
1531bce29ac9SDaniel Bristot de Oliveira static enum print_line_t
trace_osnoise_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1532bce29ac9SDaniel Bristot de Oliveira trace_osnoise_raw(struct trace_iterator *iter, int flags,
1533bce29ac9SDaniel Bristot de Oliveira struct trace_event *event)
1534bce29ac9SDaniel Bristot de Oliveira {
1535bce29ac9SDaniel Bristot de Oliveira struct osnoise_entry *field;
1536bce29ac9SDaniel Bristot de Oliveira struct trace_seq *s = &iter->seq;
1537bce29ac9SDaniel Bristot de Oliveira
1538bce29ac9SDaniel Bristot de Oliveira trace_assign_type(field, iter->ent);
1539bce29ac9SDaniel Bristot de Oliveira
1540bce29ac9SDaniel Bristot de Oliveira trace_seq_printf(s, "%lld %llu %llu %u %u %u %u %u\n",
1541bce29ac9SDaniel Bristot de Oliveira field->runtime,
1542bce29ac9SDaniel Bristot de Oliveira field->noise,
1543bce29ac9SDaniel Bristot de Oliveira field->max_sample,
1544bce29ac9SDaniel Bristot de Oliveira field->hw_count,
1545bce29ac9SDaniel Bristot de Oliveira field->nmi_count,
1546bce29ac9SDaniel Bristot de Oliveira field->irq_count,
1547bce29ac9SDaniel Bristot de Oliveira field->softirq_count,
1548bce29ac9SDaniel Bristot de Oliveira field->thread_count);
1549bce29ac9SDaniel Bristot de Oliveira
1550bce29ac9SDaniel Bristot de Oliveira return trace_handle_return(s);
1551bce29ac9SDaniel Bristot de Oliveira }
1552bce29ac9SDaniel Bristot de Oliveira
1553bce29ac9SDaniel Bristot de Oliveira static struct trace_event_functions trace_osnoise_funcs = {
1554bce29ac9SDaniel Bristot de Oliveira .trace = trace_osnoise_print,
1555bce29ac9SDaniel Bristot de Oliveira .raw = trace_osnoise_raw,
1556bce29ac9SDaniel Bristot de Oliveira };
1557bce29ac9SDaniel Bristot de Oliveira
1558bce29ac9SDaniel Bristot de Oliveira static struct trace_event trace_osnoise_event = {
1559bce29ac9SDaniel Bristot de Oliveira .type = TRACE_OSNOISE,
1560bce29ac9SDaniel Bristot de Oliveira .funcs = &trace_osnoise_funcs,
1561bce29ac9SDaniel Bristot de Oliveira };
1562bce29ac9SDaniel Bristot de Oliveira
1563a955d7eaSDaniel Bristot de Oliveira /* TRACE_TIMERLAT */
1564e88ed227SDaniel Bristot de Oliveira
1565e88ed227SDaniel Bristot de Oliveira static char *timerlat_lat_context[] = {"irq", "thread", "user-ret"};
1566a955d7eaSDaniel Bristot de Oliveira static enum print_line_t
trace_timerlat_print(struct trace_iterator * iter,int flags,struct trace_event * event)1567a955d7eaSDaniel Bristot de Oliveira trace_timerlat_print(struct trace_iterator *iter, int flags,
1568a955d7eaSDaniel Bristot de Oliveira struct trace_event *event)
1569a955d7eaSDaniel Bristot de Oliveira {
1570a955d7eaSDaniel Bristot de Oliveira struct trace_entry *entry = iter->ent;
1571a955d7eaSDaniel Bristot de Oliveira struct trace_seq *s = &iter->seq;
1572a955d7eaSDaniel Bristot de Oliveira struct timerlat_entry *field;
1573a955d7eaSDaniel Bristot de Oliveira
1574a955d7eaSDaniel Bristot de Oliveira trace_assign_type(field, entry);
1575a955d7eaSDaniel Bristot de Oliveira
1576a955d7eaSDaniel Bristot de Oliveira trace_seq_printf(s, "#%-5u context %6s timer_latency %9llu ns\n",
1577a955d7eaSDaniel Bristot de Oliveira field->seqnum,
1578e88ed227SDaniel Bristot de Oliveira timerlat_lat_context[field->context],
1579a955d7eaSDaniel Bristot de Oliveira field->timer_latency);
1580a955d7eaSDaniel Bristot de Oliveira
1581a955d7eaSDaniel Bristot de Oliveira return trace_handle_return(s);
1582a955d7eaSDaniel Bristot de Oliveira }
1583a955d7eaSDaniel Bristot de Oliveira
1584a955d7eaSDaniel Bristot de Oliveira static enum print_line_t
trace_timerlat_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1585a955d7eaSDaniel Bristot de Oliveira trace_timerlat_raw(struct trace_iterator *iter, int flags,
1586a955d7eaSDaniel Bristot de Oliveira struct trace_event *event)
1587a955d7eaSDaniel Bristot de Oliveira {
1588a955d7eaSDaniel Bristot de Oliveira struct timerlat_entry *field;
1589a955d7eaSDaniel Bristot de Oliveira struct trace_seq *s = &iter->seq;
1590a955d7eaSDaniel Bristot de Oliveira
1591a955d7eaSDaniel Bristot de Oliveira trace_assign_type(field, iter->ent);
1592a955d7eaSDaniel Bristot de Oliveira
1593a955d7eaSDaniel Bristot de Oliveira trace_seq_printf(s, "%u %d %llu\n",
1594a955d7eaSDaniel Bristot de Oliveira field->seqnum,
1595a955d7eaSDaniel Bristot de Oliveira field->context,
1596a955d7eaSDaniel Bristot de Oliveira field->timer_latency);
1597a955d7eaSDaniel Bristot de Oliveira
1598a955d7eaSDaniel Bristot de Oliveira return trace_handle_return(s);
1599a955d7eaSDaniel Bristot de Oliveira }
1600a955d7eaSDaniel Bristot de Oliveira
1601a955d7eaSDaniel Bristot de Oliveira static struct trace_event_functions trace_timerlat_funcs = {
1602a955d7eaSDaniel Bristot de Oliveira .trace = trace_timerlat_print,
1603a955d7eaSDaniel Bristot de Oliveira .raw = trace_timerlat_raw,
1604a955d7eaSDaniel Bristot de Oliveira };
1605a955d7eaSDaniel Bristot de Oliveira
1606a955d7eaSDaniel Bristot de Oliveira static struct trace_event trace_timerlat_event = {
1607a955d7eaSDaniel Bristot de Oliveira .type = TRACE_TIMERLAT,
1608a955d7eaSDaniel Bristot de Oliveira .funcs = &trace_timerlat_funcs,
1609a955d7eaSDaniel Bristot de Oliveira };
1610a955d7eaSDaniel Bristot de Oliveira
161109ae7234SSteven Rostedt (Red Hat) /* TRACE_BPUTS */
161209ae7234SSteven Rostedt (Red Hat) static enum print_line_t
trace_bputs_print(struct trace_iterator * iter,int flags,struct trace_event * event)161309ae7234SSteven Rostedt (Red Hat) trace_bputs_print(struct trace_iterator *iter, int flags,
161409ae7234SSteven Rostedt (Red Hat) struct trace_event *event)
161509ae7234SSteven Rostedt (Red Hat) {
161609ae7234SSteven Rostedt (Red Hat) struct trace_entry *entry = iter->ent;
161709ae7234SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
161809ae7234SSteven Rostedt (Red Hat) struct bputs_entry *field;
161909ae7234SSteven Rostedt (Red Hat)
162009ae7234SSteven Rostedt (Red Hat) trace_assign_type(field, entry);
162109ae7234SSteven Rostedt (Red Hat)
162219a7fe20SSteven Rostedt (Red Hat) seq_print_ip_sym(s, field->ip, flags);
162319a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, ": ");
162419a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, field->str);
162509ae7234SSteven Rostedt (Red Hat)
162619a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
162709ae7234SSteven Rostedt (Red Hat) }
162809ae7234SSteven Rostedt (Red Hat)
162909ae7234SSteven Rostedt (Red Hat)
163009ae7234SSteven Rostedt (Red Hat) static enum print_line_t
trace_bputs_raw(struct trace_iterator * iter,int flags,struct trace_event * event)163109ae7234SSteven Rostedt (Red Hat) trace_bputs_raw(struct trace_iterator *iter, int flags,
163209ae7234SSteven Rostedt (Red Hat) struct trace_event *event)
163309ae7234SSteven Rostedt (Red Hat) {
163409ae7234SSteven Rostedt (Red Hat) struct bputs_entry *field;
163509ae7234SSteven Rostedt (Red Hat) struct trace_seq *s = &iter->seq;
163609ae7234SSteven Rostedt (Red Hat)
163709ae7234SSteven Rostedt (Red Hat) trace_assign_type(field, iter->ent);
163809ae7234SSteven Rostedt (Red Hat)
163919a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, ": %lx : ", field->ip);
164019a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, field->str);
164109ae7234SSteven Rostedt (Red Hat)
164219a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
164309ae7234SSteven Rostedt (Red Hat) }
164409ae7234SSteven Rostedt (Red Hat)
164509ae7234SSteven Rostedt (Red Hat) static struct trace_event_functions trace_bputs_funcs = {
164609ae7234SSteven Rostedt (Red Hat) .trace = trace_bputs_print,
164709ae7234SSteven Rostedt (Red Hat) .raw = trace_bputs_raw,
164809ae7234SSteven Rostedt (Red Hat) };
164909ae7234SSteven Rostedt (Red Hat)
165009ae7234SSteven Rostedt (Red Hat) static struct trace_event trace_bputs_event = {
165109ae7234SSteven Rostedt (Red Hat) .type = TRACE_BPUTS,
165209ae7234SSteven Rostedt (Red Hat) .funcs = &trace_bputs_funcs,
165309ae7234SSteven Rostedt (Red Hat) };
165409ae7234SSteven Rostedt (Red Hat)
165548ead020SFrederic Weisbecker /* TRACE_BPRINT */
16561427cdf0SLai Jiangshan static enum print_line_t
trace_bprint_print(struct trace_iterator * iter,int flags,struct trace_event * event)1657a9a57763SSteven Rostedt trace_bprint_print(struct trace_iterator *iter, int flags,
1658a9a57763SSteven Rostedt struct trace_event *event)
16591427cdf0SLai Jiangshan {
16601427cdf0SLai Jiangshan struct trace_entry *entry = iter->ent;
16611427cdf0SLai Jiangshan struct trace_seq *s = &iter->seq;
166248ead020SFrederic Weisbecker struct bprint_entry *field;
16631427cdf0SLai Jiangshan
16641427cdf0SLai Jiangshan trace_assign_type(field, entry);
16651427cdf0SLai Jiangshan
166619a7fe20SSteven Rostedt (Red Hat) seq_print_ip_sym(s, field->ip, flags);
166719a7fe20SSteven Rostedt (Red Hat) trace_seq_puts(s, ": ");
166819a7fe20SSteven Rostedt (Red Hat) trace_seq_bprintf(s, field->fmt, field->buf);
16691427cdf0SLai Jiangshan
167019a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
16711427cdf0SLai Jiangshan }
16721427cdf0SLai Jiangshan
16731427cdf0SLai Jiangshan
167448ead020SFrederic Weisbecker static enum print_line_t
trace_bprint_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1675a9a57763SSteven Rostedt trace_bprint_raw(struct trace_iterator *iter, int flags,
1676a9a57763SSteven Rostedt struct trace_event *event)
1677769b0441SFrederic Weisbecker {
167848ead020SFrederic Weisbecker struct bprint_entry *field;
1679769b0441SFrederic Weisbecker struct trace_seq *s = &iter->seq;
1680769b0441SFrederic Weisbecker
1681769b0441SFrederic Weisbecker trace_assign_type(field, iter->ent);
16821427cdf0SLai Jiangshan
168319a7fe20SSteven Rostedt (Red Hat) trace_seq_printf(s, ": %lx : ", field->ip);
168419a7fe20SSteven Rostedt (Red Hat) trace_seq_bprintf(s, field->fmt, field->buf);
16851427cdf0SLai Jiangshan
168619a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
16871427cdf0SLai Jiangshan }
16881427cdf0SLai Jiangshan
1689a9a57763SSteven Rostedt static struct trace_event_functions trace_bprint_funcs = {
169048ead020SFrederic Weisbecker .trace = trace_bprint_print,
169148ead020SFrederic Weisbecker .raw = trace_bprint_raw,
169248ead020SFrederic Weisbecker };
169348ead020SFrederic Weisbecker
1694a9a57763SSteven Rostedt static struct trace_event trace_bprint_event = {
1695a9a57763SSteven Rostedt .type = TRACE_BPRINT,
1696a9a57763SSteven Rostedt .funcs = &trace_bprint_funcs,
1697a9a57763SSteven Rostedt };
1698a9a57763SSteven Rostedt
169948ead020SFrederic Weisbecker /* TRACE_PRINT */
trace_print_print(struct trace_iterator * iter,int flags,struct trace_event * event)170048ead020SFrederic Weisbecker static enum print_line_t trace_print_print(struct trace_iterator *iter,
1701a9a57763SSteven Rostedt int flags, struct trace_event *event)
170248ead020SFrederic Weisbecker {
170348ead020SFrederic Weisbecker struct print_entry *field;
170448ead020SFrederic Weisbecker struct trace_seq *s = &iter->seq;
17059b7bdf6fSSteven Rostedt unsigned long ip;
170648ead020SFrederic Weisbecker
170748ead020SFrederic Weisbecker trace_assign_type(field, iter->ent);
170848ead020SFrederic Weisbecker
17099b7bdf6fSSteven Rostedt ip = field->ip + iter->tr->text_delta;
17109b7bdf6fSSteven Rostedt
17119b7bdf6fSSteven Rostedt seq_print_ip_sym(s, ip, flags);
17125efd3e2aSSteven Rostedt (Google) trace_seq_printf(s, ": %s", field->buf);
171348ead020SFrederic Weisbecker
171419a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(s);
171548ead020SFrederic Weisbecker }
171648ead020SFrederic Weisbecker
trace_print_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1717a9a57763SSteven Rostedt static enum print_line_t trace_print_raw(struct trace_iterator *iter, int flags,
1718a9a57763SSteven Rostedt struct trace_event *event)
171948ead020SFrederic Weisbecker {
172048ead020SFrederic Weisbecker struct print_entry *field;
172148ead020SFrederic Weisbecker
172248ead020SFrederic Weisbecker trace_assign_type(field, iter->ent);
172348ead020SFrederic Weisbecker
17245efd3e2aSSteven Rostedt (Google) trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf);
172548ead020SFrederic Weisbecker
172619a7fe20SSteven Rostedt (Red Hat) return trace_handle_return(&iter->seq);
172748ead020SFrederic Weisbecker }
172848ead020SFrederic Weisbecker
1729a9a57763SSteven Rostedt static struct trace_event_functions trace_print_funcs = {
1730769b0441SFrederic Weisbecker .trace = trace_print_print,
1731769b0441SFrederic Weisbecker .raw = trace_print_raw,
17321427cdf0SLai Jiangshan };
17331427cdf0SLai Jiangshan
1734a9a57763SSteven Rostedt static struct trace_event trace_print_event = {
1735a9a57763SSteven Rostedt .type = TRACE_PRINT,
1736a9a57763SSteven Rostedt .funcs = &trace_print_funcs,
1737a9a57763SSteven Rostedt };
1738a9a57763SSteven Rostedt
trace_raw_data(struct trace_iterator * iter,int flags,struct trace_event * event)1739fa32e855SSteven Rostedt static enum print_line_t trace_raw_data(struct trace_iterator *iter, int flags,
1740fa32e855SSteven Rostedt struct trace_event *event)
1741fa32e855SSteven Rostedt {
1742fa32e855SSteven Rostedt struct raw_data_entry *field;
1743fa32e855SSteven Rostedt int i;
1744fa32e855SSteven Rostedt
1745fa32e855SSteven Rostedt trace_assign_type(field, iter->ent);
1746fa32e855SSteven Rostedt
1747fa32e855SSteven Rostedt trace_seq_printf(&iter->seq, "# %x buf:", field->id);
1748fa32e855SSteven Rostedt
1749fa32e855SSteven Rostedt for (i = 0; i < iter->ent_size - offsetof(struct raw_data_entry, buf); i++)
1750fa32e855SSteven Rostedt trace_seq_printf(&iter->seq, " %02x",
1751fa32e855SSteven Rostedt (unsigned char)field->buf[i]);
1752fa32e855SSteven Rostedt
1753fa32e855SSteven Rostedt trace_seq_putc(&iter->seq, '\n');
1754fa32e855SSteven Rostedt
1755fa32e855SSteven Rostedt return trace_handle_return(&iter->seq);
1756fa32e855SSteven Rostedt }
1757fa32e855SSteven Rostedt
1758fa32e855SSteven Rostedt static struct trace_event_functions trace_raw_data_funcs = {
1759fa32e855SSteven Rostedt .trace = trace_raw_data,
1760fa32e855SSteven Rostedt .raw = trace_raw_data,
1761fa32e855SSteven Rostedt };
1762fa32e855SSteven Rostedt
1763fa32e855SSteven Rostedt static struct trace_event trace_raw_data_event = {
1764fa32e855SSteven Rostedt .type = TRACE_RAW_DATA,
1765fa32e855SSteven Rostedt .funcs = &trace_raw_data_funcs,
1766fa32e855SSteven Rostedt };
1767fa32e855SSteven Rostedt
1768f689e4f2SYordan Karadzhov (VMware) static enum print_line_t
trace_func_repeats_raw(struct trace_iterator * iter,int flags,struct trace_event * event)1769f689e4f2SYordan Karadzhov (VMware) trace_func_repeats_raw(struct trace_iterator *iter, int flags,
1770f689e4f2SYordan Karadzhov (VMware) struct trace_event *event)
1771f689e4f2SYordan Karadzhov (VMware) {
1772f689e4f2SYordan Karadzhov (VMware) struct func_repeats_entry *field;
1773f689e4f2SYordan Karadzhov (VMware) struct trace_seq *s = &iter->seq;
1774f689e4f2SYordan Karadzhov (VMware)
1775f689e4f2SYordan Karadzhov (VMware) trace_assign_type(field, iter->ent);
1776f689e4f2SYordan Karadzhov (VMware)
1777f689e4f2SYordan Karadzhov (VMware) trace_seq_printf(s, "%lu %lu %u %llu\n",
1778f689e4f2SYordan Karadzhov (VMware) field->ip,
1779f689e4f2SYordan Karadzhov (VMware) field->parent_ip,
1780f689e4f2SYordan Karadzhov (VMware) field->count,
1781f689e4f2SYordan Karadzhov (VMware) FUNC_REPEATS_GET_DELTA_TS(field));
1782f689e4f2SYordan Karadzhov (VMware)
1783f689e4f2SYordan Karadzhov (VMware) return trace_handle_return(s);
1784f689e4f2SYordan Karadzhov (VMware) }
1785f689e4f2SYordan Karadzhov (VMware)
1786f689e4f2SYordan Karadzhov (VMware) static enum print_line_t
trace_func_repeats_print(struct trace_iterator * iter,int flags,struct trace_event * event)1787f689e4f2SYordan Karadzhov (VMware) trace_func_repeats_print(struct trace_iterator *iter, int flags,
1788f689e4f2SYordan Karadzhov (VMware) struct trace_event *event)
1789f689e4f2SYordan Karadzhov (VMware) {
1790f689e4f2SYordan Karadzhov (VMware) struct func_repeats_entry *field;
1791f689e4f2SYordan Karadzhov (VMware) struct trace_seq *s = &iter->seq;
1792f689e4f2SYordan Karadzhov (VMware)
1793f689e4f2SYordan Karadzhov (VMware) trace_assign_type(field, iter->ent);
1794f689e4f2SYordan Karadzhov (VMware)
179576fe0337SSven Schnelle print_fn_trace(s, field->ip, field->parent_ip, iter->tr->text_delta, NULL, flags);
1796f689e4f2SYordan Karadzhov (VMware) trace_seq_printf(s, " (repeats: %u, last_ts:", field->count);
1797f689e4f2SYordan Karadzhov (VMware) trace_print_time(s, iter,
1798f689e4f2SYordan Karadzhov (VMware) iter->ts - FUNC_REPEATS_GET_DELTA_TS(field));
1799f689e4f2SYordan Karadzhov (VMware) trace_seq_puts(s, ")\n");
1800f689e4f2SYordan Karadzhov (VMware)
1801f689e4f2SYordan Karadzhov (VMware) return trace_handle_return(s);
1802f689e4f2SYordan Karadzhov (VMware) }
1803f689e4f2SYordan Karadzhov (VMware)
1804f689e4f2SYordan Karadzhov (VMware) static struct trace_event_functions trace_func_repeats_funcs = {
1805f689e4f2SYordan Karadzhov (VMware) .trace = trace_func_repeats_print,
1806f689e4f2SYordan Karadzhov (VMware) .raw = trace_func_repeats_raw,
1807f689e4f2SYordan Karadzhov (VMware) };
1808f689e4f2SYordan Karadzhov (VMware)
1809f689e4f2SYordan Karadzhov (VMware) static struct trace_event trace_func_repeats_event = {
1810f689e4f2SYordan Karadzhov (VMware) .type = TRACE_FUNC_REPEATS,
1811f689e4f2SYordan Karadzhov (VMware) .funcs = &trace_func_repeats_funcs,
1812f689e4f2SYordan Karadzhov (VMware) };
181348ead020SFrederic Weisbecker
1814f633cef0SSteven Rostedt static struct trace_event *events[] __initdata = {
1815f633cef0SSteven Rostedt &trace_fn_event,
1816f633cef0SSteven Rostedt &trace_ctx_event,
1817f633cef0SSteven Rostedt &trace_wake_event,
1818f633cef0SSteven Rostedt &trace_stack_event,
1819f633cef0SSteven Rostedt &trace_user_stack_event,
182009ae7234SSteven Rostedt (Red Hat) &trace_bputs_event,
182148ead020SFrederic Weisbecker &trace_bprint_event,
1822f633cef0SSteven Rostedt &trace_print_event,
1823e7c15cd8SSteven Rostedt (Red Hat) &trace_hwlat_event,
1824bce29ac9SDaniel Bristot de Oliveira &trace_osnoise_event,
1825a955d7eaSDaniel Bristot de Oliveira &trace_timerlat_event,
1826fa32e855SSteven Rostedt &trace_raw_data_event,
1827f689e4f2SYordan Karadzhov (VMware) &trace_func_repeats_event,
1828f633cef0SSteven Rostedt NULL
1829f633cef0SSteven Rostedt };
1830f633cef0SSteven Rostedt
init_events(void)18313bb06eb6SSteven Rostedt (Google) __init int init_events(void)
1832f633cef0SSteven Rostedt {
1833f633cef0SSteven Rostedt struct trace_event *event;
1834f633cef0SSteven Rostedt int i, ret;
1835f633cef0SSteven Rostedt
1836f633cef0SSteven Rostedt for (i = 0; events[i]; i++) {
1837f633cef0SSteven Rostedt event = events[i];
18389023c930SSteven Rostedt (Red Hat) ret = register_trace_event(event);
18394ee51101SGuo Zhengkui WARN_ONCE(!ret, "event %d failed to register", event->type);
1840f633cef0SSteven Rostedt }
1841f633cef0SSteven Rostedt
1842f633cef0SSteven Rostedt return 0;
1843f633cef0SSteven Rostedt }
1844