Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ba28e02 authored by Lai Jiangshan's avatar Lai Jiangshan Committed by Ingo Molnar
Browse files

tracing: add trace_bprintk()



Impact: add a generic printk() for tracing, like trace_printk()

trace_bprintk() uses the infrastructure to record events on ring_buffer.

[ fweisbec@gmail.com: ported to latest -tip, made it work if
  !CONFIG_MODULES, never free the format strings from modules
  because we can't keep track of them and conditionnaly create
  the ftrace format strings section (reported by Steven Rostedt) ]

Signed-off-by: default avatarLai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Acked-by: default avatarSteven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1236356510-8381-4-git-send-email-fweisbec@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 1427cdf0
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -69,6 +69,14 @@
#define FTRACE_EVENTS()
#endif

#ifdef CONFIG_TRACING
#define TRACE_PRINTKS() VMLINUX_SYMBOL(__start___trace_bprintk_fmt) = .;      \
			 *(__trace_printk_fmt) /* Trace_printk fmt' pointer */ \
			 VMLINUX_SYMBOL(__stop___trace_bprintk_fmt) = .;
#else
#define TRACE_PRINTKS()
#endif

/* .data section */
#define DATA_DATA							\
	*(.data)							\
@@ -100,6 +108,7 @@
		*(__vermagic)		/* Kernel version magic */	\
		*(__markers_strings)	/* Markers: strings */		\
		*(__tracepoints_strings)/* Tracepoints: strings */	\
		TRACE_PRINTKS()					\
	}								\
									\
	.rodata1          : AT(ADDR(.rodata1) - LOAD_OFFSET) {		\
+21 −0
Original line number Diff line number Diff line
@@ -225,6 +225,27 @@ extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);

#ifdef CONFIG_TRACE_BPRINTK
extern int trace_vbprintk(unsigned long ip, const char *fmt, va_list args);
extern int __trace_bprintk(unsigned long ip, const char *fmt, ...)
		__attribute__ ((format (printf, 2, 3)));

static inline void  ____trace_bprintk_check_format(const char *fmt, ...)
		__attribute__ ((format (printf, 1, 2)));
static inline void ____trace_bprintk_check_format(const char *fmt, ...) {}
#define __trace_bprintk_check_format(fmt, args...)			\
do {									\
	if (0)								\
		____trace_bprintk_check_format(fmt, ##args);		\
} while (0)

#define trace_bprintk(fmt, args...)					\
do {									\
	static char *__attribute__((section("__trace_bprintk_fmt")))	\
			trace_bprintk_fmt = fmt;			\
	__trace_bprintk_check_format(fmt, ##args);			\
	__trace_bprintk(_THIS_IP_, trace_bprintk_fmt, ##args);	\
} while (0)
#else
#define trace_bprintk trace_printk
#endif

/* May be defined in arch */
+5 −0
Original line number Diff line number Diff line
@@ -329,6 +329,11 @@ struct module
	unsigned int num_tracepoints;
#endif

#ifdef CONFIG_TRACE_BPRINTK
	const char **trace_bprintk_fmt_start;
	unsigned int num_trace_bprintk_fmt;
#endif

#ifdef CONFIG_MODULE_UNLOAD
	/* What modules depend on me? */
	struct list_head modules_which_use_me;
+6 −0
Original line number Diff line number Diff line
@@ -2158,6 +2158,12 @@ static noinline struct module *load_module(void __user *umod,
					&mod->num_tracepoints);
#endif

#ifdef CONFIG_TRACE_BPRINTK
	mod->trace_bprintk_fmt_start = section_objs(hdr, sechdrs, secstrings,
			"__trace_bprintk_fmt", sizeof(char *),
			&mod->num_trace_bprintk_fmt);
#endif

#ifdef CONFIG_MODVERSIONS
	if ((mod->num_syms && !mod->crcs)
	    || (mod->num_gpl_syms && !mod->gpl_crcs)
+15 −0
Original line number Diff line number Diff line
@@ -3848,6 +3848,21 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
}
EXPORT_SYMBOL_GPL(trace_vbprintk);

int __trace_bprintk(unsigned long ip, const char *fmt, ...)
{
	int ret;
	va_list ap;

	if (!fmt)
		return 0;

	va_start(ap, fmt);
	ret = trace_vbprintk(ip, fmt, ap);
	va_end(ap);
	return ret;
}
EXPORT_SYMBOL_GPL(__trace_bprintk);

static int trace_panic_handler(struct notifier_block *this,
			       unsigned long event, void *unused)
{
Loading