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