tracing/core: bring back raw trace_printk for dynamic formats strings
Impact: fix callsites with dynamic format strings Since its new binary implementation, trace_printk() internally uses static containers for the format strings on each callsites. But the value is assigned once at build time, which means that it can't take dynamic formats. So this patch unearthes the raw trace_printk implementation for the callers that will need trace_printk to be able to carry these dynamic format strings. The trace_printk() macro will use the appropriate implementation for each callsite. Most of the time however, the binary implementation will still be used. The other impact of this patch is that mmiotrace_printk() will use the old implementation because it calls the low level trace_vprintk and we can't guess here whether the format passed in it is dynamic or not. Some parts of this patch have been written by Steven Rostedt (most notably the part that chooses the appropriate implementation for each callsites). Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Signed-off-by: Steven Rostedt <srostedt@redhat.com>
This commit is contained in:
committed by
Steven Rostedt
parent
db526ca329
commit
48ead02030
@@ -452,31 +452,45 @@ do { \
|
||||
|
||||
#define trace_printk(fmt, args...) \
|
||||
do { \
|
||||
static const char *trace_printk_fmt \
|
||||
__attribute__((section("__trace_printk_fmt"))); \
|
||||
\
|
||||
if (!trace_printk_fmt) \
|
||||
trace_printk_fmt = fmt; \
|
||||
\
|
||||
__trace_printk_check_format(fmt, ##args); \
|
||||
__trace_printk(_THIS_IP_, trace_printk_fmt, ##args); \
|
||||
if (__builtin_constant_p(fmt)) { \
|
||||
static const char *trace_printk_fmt \
|
||||
__attribute__((section("__trace_printk_fmt"))) = \
|
||||
__builtin_constant_p(fmt) ? fmt : NULL; \
|
||||
\
|
||||
__trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \
|
||||
} else \
|
||||
__trace_printk(_THIS_IP_, fmt, ##args); \
|
||||
} while (0)
|
||||
|
||||
extern int
|
||||
__trace_bprintk(unsigned long ip, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
extern int
|
||||
__trace_printk(unsigned long ip, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
/*
|
||||
* The double __builtin_constant_p is because gcc will give us an error
|
||||
* if we try to allocate the static variable to fmt if it is not a
|
||||
* constant. Even with the outer if statement.
|
||||
*/
|
||||
#define ftrace_vprintk(fmt, vargs) \
|
||||
do { \
|
||||
static const char *trace_printk_fmt \
|
||||
__attribute__((section("__trace_printk_fmt"))); \
|
||||
if (__builtin_constant_p(fmt)) { \
|
||||
static const char *trace_printk_fmt \
|
||||
__attribute__((section("__trace_printk_fmt"))) = \
|
||||
__builtin_constant_p(fmt) ? fmt : NULL; \
|
||||
\
|
||||
if (!trace_printk_fmt) \
|
||||
trace_printk_fmt = fmt; \
|
||||
\
|
||||
__ftrace_vprintk(_THIS_IP_, trace_printk_fmt, vargs); \
|
||||
__ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \
|
||||
} else \
|
||||
__ftrace_vprintk(_THIS_IP_, fmt, vargs); \
|
||||
} while (0)
|
||||
|
||||
extern int
|
||||
__ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap);
|
||||
|
||||
extern int
|
||||
__ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap);
|
||||
|
||||
|
Reference in New Issue
Block a user