diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-05-26 14:25:22 -0400 |
---|---|---|
committer | Frederic Weisbecker <fweisbec@gmail.com> | 2009-05-26 14:25:22 -0400 |
commit | be74b73a57645cc253d881ab0c1014eb64b9cf22 (patch) | |
tree | 83f14ae9a43fe98a1363d30d20d60245e1115382 /kernel | |
parent | 0e907c99391362385c8e3af2c43b904dd1fd5d73 (diff) |
tracing: add __print_flags for events
Developers have been asking for the ability in the ftrace event tracer
to display names of bits in a flags variable.
Instead of printing out c2, it would be easier to read FOO|BAR|GOO,
assuming that FOO is bit 1, BAR is bit 6 and GOO is bit 7.
Some examples where this would be useful are the state flags in a context
switch, kmalloc flags, and even permision flags in accessing files.
[
v2 changes include:
Frederic Weisbecker's idea of using a mask instead of bits,
thus we can output GFP_KERNEL instead of GPF_WAIT|GFP_IO|GFP_FS.
Li Zefan's idea of allowing the caller of __print_flags to add their
own delimiter (or no delimiter) where we can get for file permissions
rwx instead of r|w|x.
]
[
v3 changes:
Christoph Hellwig's idea of using an array instead of va_args.
]
[ Impact: better displaying of flags in trace output ]
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/trace_output.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 7136420603aa..a4840c260c89 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #define EVENT_HASHSIZE 128 | 15 | #define EVENT_HASHSIZE 128 |
16 | 16 | ||
17 | static DECLARE_RWSEM(trace_event_mutex); | 17 | static DECLARE_RWSEM(trace_event_mutex); |
18 | |||
19 | DEFINE_PER_CPU(struct trace_seq, ftrace_event_seq); | ||
20 | |||
18 | static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly; | 21 | static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly; |
19 | 22 | ||
20 | static int next_event_type = __TRACE_LAST_TYPE + 1; | 23 | static int next_event_type = __TRACE_LAST_TYPE + 1; |
@@ -212,6 +215,42 @@ int trace_seq_path(struct trace_seq *s, struct path *path) | |||
212 | return 0; | 215 | return 0; |
213 | } | 216 | } |
214 | 217 | ||
218 | const char * | ||
219 | ftrace_print_flags_seq(struct trace_seq *p, const char *delim, | ||
220 | unsigned long flags, | ||
221 | const struct trace_print_flags *flag_array) | ||
222 | { | ||
223 | unsigned long mask; | ||
224 | const char *str; | ||
225 | int i; | ||
226 | |||
227 | trace_seq_init(p); | ||
228 | |||
229 | for (i = 0; flag_array[i].name && flags; i++) { | ||
230 | |||
231 | mask = flag_array[i].mask; | ||
232 | if ((flags & mask) != mask) | ||
233 | continue; | ||
234 | |||
235 | str = flag_array[i].name; | ||
236 | flags &= ~mask; | ||
237 | if (p->len && delim) | ||
238 | trace_seq_puts(p, delim); | ||
239 | trace_seq_puts(p, str); | ||
240 | } | ||
241 | |||
242 | /* check for left over flags */ | ||
243 | if (flags) { | ||
244 | if (p->len && delim) | ||
245 | trace_seq_puts(p, delim); | ||
246 | trace_seq_printf(p, "0x%lx", flags); | ||
247 | } | ||
248 | |||
249 | trace_seq_putc(p, 0); | ||
250 | |||
251 | return p->buffer; | ||
252 | } | ||
253 | |||
215 | #ifdef CONFIG_KRETPROBES | 254 | #ifdef CONFIG_KRETPROBES |
216 | static inline const char *kretprobed(const char *name) | 255 | static inline const char *kretprobed(const char *name) |
217 | { | 256 | { |