aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-04-11 12:59:57 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-04-14 12:57:57 -0400
commit9504504cbab29ecb694186b1c5b15d3579c43c51 (patch)
treefd91bec634dfff191699616523812a3d4ffe6348
parenta8d154b009168337494fbf345671bab74d3e4b8b (diff)
tracing: make trace_seq operations available for core kernel
In the process to make TRACE_EVENT macro work for modules, the trace_seq operations must be available for core kernel code. These operations are quite useful and can be used for other implementations. The main idea is that we create a trace_seq handle that acts very much like the seq_file handle. struct trace_seq *s = kmalloc(sizeof(*s, GFP_KERNEL); trace_seq_init(s); trace_seq_printf(s, "some data %d\n", variable); printk("%s", s->buffer); The main use is to allow a top level function call several other functions that may store printf like data into the buffer. Then at the end, the top level function can process all the data with any method it would like to. It could be passed to userspace, output via printk or even use seq_file: trace_seq_to_user(s, ubuf, cnt); seq_puts(m, s->buffer); Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--include/linux/trace_seq.h89
-rw-r--r--kernel/trace/trace.h15
-rw-r--r--kernel/trace/trace_output.h16
3 files changed, 92 insertions, 28 deletions
diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h
new file mode 100644
index 000000000000..28051da876dd
--- /dev/null
+++ b/include/linux/trace_seq.h
@@ -0,0 +1,89 @@
1#ifndef _LINUX_TRACE_SEQ_H
2#define _LINUX_TRACE_SEQ_H
3
4/*
5 * Trace sequences are used to allow a function to call several other functions
6 * to create a string of data to use (up to a max of PAGE_SIZE.
7 */
8
9struct trace_seq {
10 unsigned char buffer[PAGE_SIZE];
11 unsigned int len;
12 unsigned int readpos;
13};
14
15static inline void
16trace_seq_init(struct trace_seq *s)
17{
18 s->len = 0;
19 s->readpos = 0;
20}
21
22/*
23 * Currently only defined when tracing is enabled.
24 */
25#ifdef CONFIG_TRACING
26extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
27 __attribute__ ((format (printf, 2, 3)));
28extern int
29trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
30extern void trace_print_seq(struct seq_file *m, struct trace_seq *s);
31extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
32 size_t cnt);
33extern int trace_seq_puts(struct trace_seq *s, const char *str);
34extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
35extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len);
36extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
37 size_t len);
38extern void *trace_seq_reserve(struct trace_seq *s, size_t len);
39extern int trace_seq_path(struct trace_seq *s, struct path *path);
40
41#else /* CONFIG_TRACING */
42static inline int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
43 __attribute__ ((format (printf, 2, 3)))
44{
45 return 0;
46}
47static inline int
48trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
49{
50 return 0;
51}
52
53static inline void trace_print_seq(struct seq_file *m, struct trace_seq *s)
54{
55}
56static inline ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
57 size_t cnt)
58{
59 return 0;
60}
61static inline int trace_seq_puts(struct trace_seq *s, const char *str)
62{
63 return 0;
64}
65static inline int trace_seq_putc(struct trace_seq *s, unsigned char c);
66{
67 return 0;
68}
69static inline int
70trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
71{
72 return 0;
73}
74static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
75 size_t len)
76{
77 return 0;
78}
79static inline void *trace_seq_reserve(struct trace_seq *s, size_t len)
80{
81 return NULL;
82}
83static inline int trace_seq_path(struct trace_seq *s, struct path *path)
84{
85 return 0;
86}
87#endif /* CONFIG_TRACING */
88
89#endif /* _LINUX_TRACE_SEQ_H */
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index b05b6ac982a1..1882846b7389 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -12,6 +12,8 @@
12#include <linux/kmemtrace.h> 12#include <linux/kmemtrace.h>
13#include <trace/power.h> 13#include <trace/power.h>
14 14
15#include <linux/trace_seq.h>
16
15enum trace_type { 17enum trace_type {
16 __TRACE_FIRST_TYPE = 0, 18 __TRACE_FIRST_TYPE = 0,
17 19
@@ -423,19 +425,6 @@ struct tracer {
423 struct tracer_stat *stats; 425 struct tracer_stat *stats;
424}; 426};
425 427
426struct trace_seq {
427 unsigned char buffer[PAGE_SIZE];
428 unsigned int len;
429 unsigned int readpos;
430};
431
432static inline void
433trace_seq_init(struct trace_seq *s)
434{
435 s->len = 0;
436 s->readpos = 0;
437}
438
439 428
440#define TRACE_PIPE_ALL_CPU -1 429#define TRACE_PIPE_ALL_CPU -1
441 430
diff --git a/kernel/trace/trace_output.h b/kernel/trace/trace_output.h
index 91630217fb46..5c7cbfb65c71 100644
--- a/kernel/trace/trace_output.h
+++ b/kernel/trace/trace_output.h
@@ -1,6 +1,7 @@
1#ifndef __TRACE_EVENTS_H 1#ifndef __TRACE_EVENTS_H
2#define __TRACE_EVENTS_H 2#define __TRACE_EVENTS_H
3 3
4#include <linux/trace_seq.h>
4#include "trace.h" 5#include "trace.h"
5 6
6typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter, 7typedef enum print_line_t (*trace_print_func)(struct trace_iterator *iter,
@@ -20,24 +21,9 @@ trace_print_bprintk_msg_only(struct trace_iterator *iter);
20extern enum print_line_t 21extern enum print_line_t
21trace_print_printk_msg_only(struct trace_iterator *iter); 22trace_print_printk_msg_only(struct trace_iterator *iter);
22 23
23extern void trace_print_seq(struct seq_file *m, struct trace_seq *s);
24
25extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
26 __attribute__ ((format (printf, 2, 3)));
27extern int
28trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
29extern int 24extern int
30seq_print_ip_sym(struct trace_seq *s, unsigned long ip, 25seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
31 unsigned long sym_flags); 26 unsigned long sym_flags);
32extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
33 size_t cnt);
34extern int trace_seq_puts(struct trace_seq *s, const char *str);
35extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
36extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len);
37extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
38 size_t len);
39extern void *trace_seq_reserve(struct trace_seq *s, size_t len);
40extern int trace_seq_path(struct trace_seq *s, struct path *path);
41extern int seq_print_userip_objs(const struct userstack_entry *entry, 27extern int seq_print_userip_objs(const struct userstack_entry *entry,
42 struct trace_seq *s, unsigned long sym_flags); 28 struct trace_seq *s, unsigned long sym_flags);
43extern int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm, 29extern int seq_print_user_ip(struct trace_seq *s, struct mm_struct *mm,