diff options
Diffstat (limited to 'include/linux/kernel.h')
| -rw-r--r-- | include/linux/kernel.h | 23 | 
1 files changed, 22 insertions, 1 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index a3a5574a61f..d0a16fe03fe 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -516,9 +516,30 @@ do {									\   * Please refrain from leaving trace_printks scattered around in   * your code. (Extra memory is used for special buffers that are   * allocated when trace_printk() is used) + * + * A little optization trick is done here. If there's only one + * argument, there's no need to scan the string for printf formats. + * The trace_puts() will suffice. But how can we take advantage of + * using trace_puts() when trace_printk() has only one argument? + * By stringifying the args and checking the size we can tell + * whether or not there are args. __stringify((__VA_ARGS__)) will + * turn into "()\0" with a size of 3 when there are no args, anything + * else will be bigger. All we need to do is define a string to this, + * and then take its size and compare to 3. If it's bigger, use + * do_trace_printk() otherwise, optimize it to trace_puts(). Then just + * let gcc optimize the rest.   */ -#define trace_printk(fmt, args...)					\ +#define trace_printk(fmt, ...)				\ +do {							\ +	char _______STR[] = __stringify((__VA_ARGS__));	\ +	if (sizeof(_______STR) > 3)			\ +		do_trace_printk(fmt, ##__VA_ARGS__);	\ +	else						\ +		trace_puts(fmt);			\ +} while (0) + +#define do_trace_printk(fmt, args...)					\  do {									\  	static const char *trace_printk_fmt				\  		__attribute__((section("__trace_printk_fmt"))) =	\  |