diff options
author | Steven Rostedt <srostedt@redhat.com> | 2011-12-19 14:41:25 -0500 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2011-12-21 07:25:06 -0500 |
commit | fc13cb0ce45296f331263a6034aa1814203e1ac3 (patch) | |
tree | 2c66d6296ee01bcbd27cb9df4b72885339300ba6 /kernel/trace/ftrace.c | |
parent | 06a51d9307380c78bb5c92e68fc80ad2c7d7f890 (diff) |
ftrace: Allow other users of function tracing to use the output listing
The function tracer is set up to allow any other subsystem (like perf)
to use it. Ftrace already has a way to list what functions are enabled
by the global_ops. It would be very helpful to let other users of
the function tracer to be able to use the same code.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r-- | kernel/trace/ftrace.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index e1ee07f81ca2..5b105c5ddc0c 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -2134,14 +2134,6 @@ static int __init ftrace_dyn_table_alloc(unsigned long num_to_init) | |||
2134 | return 0; | 2134 | return 0; |
2135 | } | 2135 | } |
2136 | 2136 | ||
2137 | enum { | ||
2138 | FTRACE_ITER_FILTER = (1 << 0), | ||
2139 | FTRACE_ITER_NOTRACE = (1 << 1), | ||
2140 | FTRACE_ITER_PRINTALL = (1 << 2), | ||
2141 | FTRACE_ITER_HASH = (1 << 3), | ||
2142 | FTRACE_ITER_ENABLED = (1 << 4), | ||
2143 | }; | ||
2144 | |||
2145 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ | 2137 | #define FTRACE_BUFF_MAX (KSYM_SYMBOL_LEN+4) /* room for wildcards */ |
2146 | 2138 | ||
2147 | struct ftrace_iterator { | 2139 | struct ftrace_iterator { |
@@ -2249,7 +2241,7 @@ static void * | |||
2249 | t_next(struct seq_file *m, void *v, loff_t *pos) | 2241 | t_next(struct seq_file *m, void *v, loff_t *pos) |
2250 | { | 2242 | { |
2251 | struct ftrace_iterator *iter = m->private; | 2243 | struct ftrace_iterator *iter = m->private; |
2252 | struct ftrace_ops *ops = &global_ops; | 2244 | struct ftrace_ops *ops = iter->ops; |
2253 | struct dyn_ftrace *rec = NULL; | 2245 | struct dyn_ftrace *rec = NULL; |
2254 | 2246 | ||
2255 | if (unlikely(ftrace_disabled)) | 2247 | if (unlikely(ftrace_disabled)) |
@@ -2305,7 +2297,7 @@ static void reset_iter_read(struct ftrace_iterator *iter) | |||
2305 | static void *t_start(struct seq_file *m, loff_t *pos) | 2297 | static void *t_start(struct seq_file *m, loff_t *pos) |
2306 | { | 2298 | { |
2307 | struct ftrace_iterator *iter = m->private; | 2299 | struct ftrace_iterator *iter = m->private; |
2308 | struct ftrace_ops *ops = &global_ops; | 2300 | struct ftrace_ops *ops = iter->ops; |
2309 | void *p = NULL; | 2301 | void *p = NULL; |
2310 | loff_t l; | 2302 | loff_t l; |
2311 | 2303 | ||
@@ -2414,6 +2406,7 @@ ftrace_avail_open(struct inode *inode, struct file *file) | |||
2414 | return -ENOMEM; | 2406 | return -ENOMEM; |
2415 | 2407 | ||
2416 | iter->pg = ftrace_pages_start; | 2408 | iter->pg = ftrace_pages_start; |
2409 | iter->ops = &global_ops; | ||
2417 | 2410 | ||
2418 | ret = seq_open(file, &show_ftrace_seq_ops); | 2411 | ret = seq_open(file, &show_ftrace_seq_ops); |
2419 | if (!ret) { | 2412 | if (!ret) { |
@@ -2442,6 +2435,7 @@ ftrace_enabled_open(struct inode *inode, struct file *file) | |||
2442 | 2435 | ||
2443 | iter->pg = ftrace_pages_start; | 2436 | iter->pg = ftrace_pages_start; |
2444 | iter->flags = FTRACE_ITER_ENABLED; | 2437 | iter->flags = FTRACE_ITER_ENABLED; |
2438 | iter->ops = &global_ops; | ||
2445 | 2439 | ||
2446 | ret = seq_open(file, &show_ftrace_seq_ops); | 2440 | ret = seq_open(file, &show_ftrace_seq_ops); |
2447 | if (!ret) { | 2441 | if (!ret) { |
@@ -2462,7 +2456,23 @@ static void ftrace_filter_reset(struct ftrace_hash *hash) | |||
2462 | mutex_unlock(&ftrace_lock); | 2456 | mutex_unlock(&ftrace_lock); |
2463 | } | 2457 | } |
2464 | 2458 | ||
2465 | static int | 2459 | /** |
2460 | * ftrace_regex_open - initialize function tracer filter files | ||
2461 | * @ops: The ftrace_ops that hold the hash filters | ||
2462 | * @flag: The type of filter to process | ||
2463 | * @inode: The inode, usually passed in to your open routine | ||
2464 | * @file: The file, usually passed in to your open routine | ||
2465 | * | ||
2466 | * ftrace_regex_open() initializes the filter files for the | ||
2467 | * @ops. Depending on @flag it may process the filter hash or | ||
2468 | * the notrace hash of @ops. With this called from the open | ||
2469 | * routine, you can use ftrace_filter_write() for the write | ||
2470 | * routine if @flag has FTRACE_ITER_FILTER set, or | ||
2471 | * ftrace_notrace_write() if @flag has FTRACE_ITER_NOTRACE set. | ||
2472 | * ftrace_regex_lseek() should be used as the lseek routine, and | ||
2473 | * release must call ftrace_regex_release(). | ||
2474 | */ | ||
2475 | int | ||
2466 | ftrace_regex_open(struct ftrace_ops *ops, int flag, | 2476 | ftrace_regex_open(struct ftrace_ops *ops, int flag, |
2467 | struct inode *inode, struct file *file) | 2477 | struct inode *inode, struct file *file) |
2468 | { | 2478 | { |
@@ -2542,7 +2552,7 @@ ftrace_notrace_open(struct inode *inode, struct file *file) | |||
2542 | inode, file); | 2552 | inode, file); |
2543 | } | 2553 | } |
2544 | 2554 | ||
2545 | static loff_t | 2555 | loff_t |
2546 | ftrace_regex_lseek(struct file *file, loff_t offset, int origin) | 2556 | ftrace_regex_lseek(struct file *file, loff_t offset, int origin) |
2547 | { | 2557 | { |
2548 | loff_t ret; | 2558 | loff_t ret; |
@@ -3095,14 +3105,14 @@ out_unlock: | |||
3095 | return ret; | 3105 | return ret; |
3096 | } | 3106 | } |
3097 | 3107 | ||
3098 | static ssize_t | 3108 | ssize_t |
3099 | ftrace_filter_write(struct file *file, const char __user *ubuf, | 3109 | ftrace_filter_write(struct file *file, const char __user *ubuf, |
3100 | size_t cnt, loff_t *ppos) | 3110 | size_t cnt, loff_t *ppos) |
3101 | { | 3111 | { |
3102 | return ftrace_regex_write(file, ubuf, cnt, ppos, 1); | 3112 | return ftrace_regex_write(file, ubuf, cnt, ppos, 1); |
3103 | } | 3113 | } |
3104 | 3114 | ||
3105 | static ssize_t | 3115 | ssize_t |
3106 | ftrace_notrace_write(struct file *file, const char __user *ubuf, | 3116 | ftrace_notrace_write(struct file *file, const char __user *ubuf, |
3107 | size_t cnt, loff_t *ppos) | 3117 | size_t cnt, loff_t *ppos) |
3108 | { | 3118 | { |
@@ -3292,8 +3302,7 @@ static void __init set_ftrace_early_filters(void) | |||
3292 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 3302 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ |
3293 | } | 3303 | } |
3294 | 3304 | ||
3295 | static int | 3305 | int ftrace_regex_release(struct inode *inode, struct file *file) |
3296 | ftrace_regex_release(struct inode *inode, struct file *file) | ||
3297 | { | 3306 | { |
3298 | struct seq_file *m = (struct seq_file *)file->private_data; | 3307 | struct seq_file *m = (struct seq_file *)file->private_data; |
3299 | struct ftrace_iterator *iter; | 3308 | struct ftrace_iterator *iter; |