aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/kernel.h
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-09-22 14:01:55 -0400
committerSteven Rostedt <rostedt@goodmis.org>2012-04-23 21:15:55 -0400
commit07d777fe8c3985bc83428c2866713c2d1b3d4129 (patch)
treef14c6aa59b9719761ad9feebebca22550ebdf0e3 /include/linux/kernel.h
parenta385ec4f11bdcf81af094c03e2444ee9b7fad2e5 (diff)
tracing: Add percpu buffers for trace_printk()
Currently, trace_printk() uses a single buffer to write into to calculate the size and format needed to save the trace. To do this safely in an SMP environment, a spin_lock() is taken to only allow one writer at a time to the buffer. But this could also affect what is being traced, and add synchronization that would not be there otherwise. Ideally, using percpu buffers would be useful, but since trace_printk() is only used in development, having per cpu buffers for something never used is a waste of space. Thus, the use of the trace_bprintk() format section is changed to be used for static fmts as well as dynamic ones. Then at boot up, we can check if the section that holds the trace_printk formats is non-empty, and if it does contain something, then we know a trace_printk() has been added to the kernel. At this time the trace_printk per cpu buffers are allocated. A check is also done at module load time in case a module is added that contains a trace_printk(). Once the buffers are allocated, they are never freed. If you use a trace_printk() then you should know what you are doing. A buffer is made for each type of context: normal softirq irq nmi The context is checked and the appropriate buffer is used. This allows for totally lockless usage of trace_printk(), and they no longer even disable interrupts. Requested-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'include/linux/kernel.h')
-rw-r--r--include/linux/kernel.h13
1 files changed, 7 insertions, 6 deletions
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 645231c373c8..c0d34420a913 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -480,15 +480,16 @@ do { \
480 480
481#define trace_printk(fmt, args...) \ 481#define trace_printk(fmt, args...) \
482do { \ 482do { \
483 static const char *trace_printk_fmt \
484 __attribute__((section("__trace_printk_fmt"))) = \
485 __builtin_constant_p(fmt) ? fmt : NULL; \
486 \
483 __trace_printk_check_format(fmt, ##args); \ 487 __trace_printk_check_format(fmt, ##args); \
484 if (__builtin_constant_p(fmt)) { \
485 static const char *trace_printk_fmt \
486 __attribute__((section("__trace_printk_fmt"))) = \
487 __builtin_constant_p(fmt) ? fmt : NULL; \
488 \ 488 \
489 if (__builtin_constant_p(fmt)) \
489 __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \ 490 __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \
490 } else \ 491 else \
491 __trace_printk(_THIS_IP_, fmt, ##args); \ 492 __trace_printk(_THIS_IP_, fmt, ##args); \
492} while (0) 493} while (0)
493 494
494extern __printf(2, 3) 495extern __printf(2, 3)