aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/ftrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/ftrace.c')
-rw-r--r--kernel/trace/ftrace.c161
1 files changed, 123 insertions, 38 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 03cf44ac54d3..22fa55696760 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3307,7 +3307,11 @@ void unregister_ftrace_function_probe_all(char *glob)
3307static LIST_HEAD(ftrace_commands); 3307static LIST_HEAD(ftrace_commands);
3308static DEFINE_MUTEX(ftrace_cmd_mutex); 3308static DEFINE_MUTEX(ftrace_cmd_mutex);
3309 3309
3310int register_ftrace_command(struct ftrace_func_command *cmd) 3310/*
3311 * Currently we only register ftrace commands from __init, so mark this
3312 * __init too.
3313 */
3314__init int register_ftrace_command(struct ftrace_func_command *cmd)
3311{ 3315{
3312 struct ftrace_func_command *p; 3316 struct ftrace_func_command *p;
3313 int ret = 0; 3317 int ret = 0;
@@ -3326,7 +3330,11 @@ int register_ftrace_command(struct ftrace_func_command *cmd)
3326 return ret; 3330 return ret;
3327} 3331}
3328 3332
3329int unregister_ftrace_command(struct ftrace_func_command *cmd) 3333/*
3334 * Currently we only unregister ftrace commands from __init, so mark
3335 * this __init too.
3336 */
3337__init int unregister_ftrace_command(struct ftrace_func_command *cmd)
3330{ 3338{
3331 struct ftrace_func_command *p, *n; 3339 struct ftrace_func_command *p, *n;
3332 int ret = -ENODEV; 3340 int ret = -ENODEV;
@@ -3641,7 +3649,7 @@ __setup("ftrace_filter=", set_ftrace_filter);
3641 3649
3642#ifdef CONFIG_FUNCTION_GRAPH_TRACER 3650#ifdef CONFIG_FUNCTION_GRAPH_TRACER
3643static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; 3651static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
3644static int ftrace_set_func(unsigned long *array, int *idx, char *buffer); 3652static int ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer);
3645 3653
3646static int __init set_graph_function(char *str) 3654static int __init set_graph_function(char *str)
3647{ 3655{
@@ -3659,7 +3667,7 @@ static void __init set_ftrace_early_graph(char *buf)
3659 func = strsep(&buf, ","); 3667 func = strsep(&buf, ",");
3660 /* we allow only one expression at a time */ 3668 /* we allow only one expression at a time */
3661 ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, 3669 ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
3662 func); 3670 FTRACE_GRAPH_MAX_FUNCS, func);
3663 if (ret) 3671 if (ret)
3664 printk(KERN_DEBUG "ftrace: function %s not " 3672 printk(KERN_DEBUG "ftrace: function %s not "
3665 "traceable\n", func); 3673 "traceable\n", func);
@@ -3776,15 +3784,25 @@ static const struct file_operations ftrace_notrace_fops = {
3776static DEFINE_MUTEX(graph_lock); 3784static DEFINE_MUTEX(graph_lock);
3777 3785
3778int ftrace_graph_count; 3786int ftrace_graph_count;
3779int ftrace_graph_filter_enabled; 3787int ftrace_graph_notrace_count;
3780unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; 3788unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
3789unsigned long ftrace_graph_notrace_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
3790
3791struct ftrace_graph_data {
3792 unsigned long *table;
3793 size_t size;
3794 int *count;
3795 const struct seq_operations *seq_ops;
3796};
3781 3797
3782static void * 3798static void *
3783__g_next(struct seq_file *m, loff_t *pos) 3799__g_next(struct seq_file *m, loff_t *pos)
3784{ 3800{
3785 if (*pos >= ftrace_graph_count) 3801 struct ftrace_graph_data *fgd = m->private;
3802
3803 if (*pos >= *fgd->count)
3786 return NULL; 3804 return NULL;
3787 return &ftrace_graph_funcs[*pos]; 3805 return &fgd->table[*pos];
3788} 3806}
3789 3807
3790static void * 3808static void *
@@ -3796,10 +3814,12 @@ g_next(struct seq_file *m, void *v, loff_t *pos)
3796 3814
3797static void *g_start(struct seq_file *m, loff_t *pos) 3815static void *g_start(struct seq_file *m, loff_t *pos)
3798{ 3816{
3817 struct ftrace_graph_data *fgd = m->private;
3818
3799 mutex_lock(&graph_lock); 3819 mutex_lock(&graph_lock);
3800 3820
3801 /* Nothing, tell g_show to print all functions are enabled */ 3821 /* Nothing, tell g_show to print all functions are enabled */
3802 if (!ftrace_graph_filter_enabled && !*pos) 3822 if (!*fgd->count && !*pos)
3803 return (void *)1; 3823 return (void *)1;
3804 3824
3805 return __g_next(m, pos); 3825 return __g_next(m, pos);
@@ -3835,38 +3855,88 @@ static const struct seq_operations ftrace_graph_seq_ops = {
3835}; 3855};
3836 3856
3837static int 3857static int
3838ftrace_graph_open(struct inode *inode, struct file *file) 3858__ftrace_graph_open(struct inode *inode, struct file *file,
3859 struct ftrace_graph_data *fgd)
3839{ 3860{
3840 int ret = 0; 3861 int ret = 0;
3841 3862
3842 if (unlikely(ftrace_disabled))
3843 return -ENODEV;
3844
3845 mutex_lock(&graph_lock); 3863 mutex_lock(&graph_lock);
3846 if ((file->f_mode & FMODE_WRITE) && 3864 if ((file->f_mode & FMODE_WRITE) &&
3847 (file->f_flags & O_TRUNC)) { 3865 (file->f_flags & O_TRUNC)) {
3848 ftrace_graph_filter_enabled = 0; 3866 *fgd->count = 0;
3849 ftrace_graph_count = 0; 3867 memset(fgd->table, 0, fgd->size * sizeof(*fgd->table));
3850 memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs));
3851 } 3868 }
3852 mutex_unlock(&graph_lock); 3869 mutex_unlock(&graph_lock);
3853 3870
3854 if (file->f_mode & FMODE_READ) 3871 if (file->f_mode & FMODE_READ) {
3855 ret = seq_open(file, &ftrace_graph_seq_ops); 3872 ret = seq_open(file, fgd->seq_ops);
3873 if (!ret) {
3874 struct seq_file *m = file->private_data;
3875 m->private = fgd;
3876 }
3877 } else
3878 file->private_data = fgd;
3856 3879
3857 return ret; 3880 return ret;
3858} 3881}
3859 3882
3860static int 3883static int
3884ftrace_graph_open(struct inode *inode, struct file *file)
3885{
3886 struct ftrace_graph_data *fgd;
3887
3888 if (unlikely(ftrace_disabled))
3889 return -ENODEV;
3890
3891 fgd = kmalloc(sizeof(*fgd), GFP_KERNEL);
3892 if (fgd == NULL)
3893 return -ENOMEM;
3894
3895 fgd->table = ftrace_graph_funcs;
3896 fgd->size = FTRACE_GRAPH_MAX_FUNCS;
3897 fgd->count = &ftrace_graph_count;
3898 fgd->seq_ops = &ftrace_graph_seq_ops;
3899
3900 return __ftrace_graph_open(inode, file, fgd);
3901}
3902
3903static int
3904ftrace_graph_notrace_open(struct inode *inode, struct file *file)
3905{
3906 struct ftrace_graph_data *fgd;
3907
3908 if (unlikely(ftrace_disabled))
3909 return -ENODEV;
3910
3911 fgd = kmalloc(sizeof(*fgd), GFP_KERNEL);
3912 if (fgd == NULL)
3913 return -ENOMEM;
3914
3915 fgd->table = ftrace_graph_notrace_funcs;
3916 fgd->size = FTRACE_GRAPH_MAX_FUNCS;
3917 fgd->count = &ftrace_graph_notrace_count;
3918 fgd->seq_ops = &ftrace_graph_seq_ops;
3919
3920 return __ftrace_graph_open(inode, file, fgd);
3921}
3922
3923static int
3861ftrace_graph_release(struct inode *inode, struct file *file) 3924ftrace_graph_release(struct inode *inode, struct file *file)
3862{ 3925{
3863 if (file->f_mode & FMODE_READ) 3926 if (file->f_mode & FMODE_READ) {
3927 struct seq_file *m = file->private_data;
3928
3929 kfree(m->private);
3864 seq_release(inode, file); 3930 seq_release(inode, file);
3931 } else {
3932 kfree(file->private_data);
3933 }
3934
3865 return 0; 3935 return 0;
3866} 3936}
3867 3937
3868static int 3938static int
3869ftrace_set_func(unsigned long *array, int *idx, char *buffer) 3939ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
3870{ 3940{
3871 struct dyn_ftrace *rec; 3941 struct dyn_ftrace *rec;
3872 struct ftrace_page *pg; 3942 struct ftrace_page *pg;
@@ -3879,7 +3949,7 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
3879 3949
3880 /* decode regex */ 3950 /* decode regex */
3881 type = filter_parse_regex(buffer, strlen(buffer), &search, &not); 3951 type = filter_parse_regex(buffer, strlen(buffer), &search, &not);
3882 if (!not && *idx >= FTRACE_GRAPH_MAX_FUNCS) 3952 if (!not && *idx >= size)
3883 return -EBUSY; 3953 return -EBUSY;
3884 3954
3885 search_len = strlen(search); 3955 search_len = strlen(search);
@@ -3907,7 +3977,7 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
3907 fail = 0; 3977 fail = 0;
3908 if (!exists) { 3978 if (!exists) {
3909 array[(*idx)++] = rec->ip; 3979 array[(*idx)++] = rec->ip;
3910 if (*idx >= FTRACE_GRAPH_MAX_FUNCS) 3980 if (*idx >= size)
3911 goto out; 3981 goto out;
3912 } 3982 }
3913 } else { 3983 } else {
@@ -3925,8 +3995,6 @@ out:
3925 if (fail) 3995 if (fail)
3926 return -EINVAL; 3996 return -EINVAL;
3927 3997
3928 ftrace_graph_filter_enabled = !!(*idx);
3929
3930 return 0; 3998 return 0;
3931} 3999}
3932 4000
@@ -3935,36 +4003,33 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
3935 size_t cnt, loff_t *ppos) 4003 size_t cnt, loff_t *ppos)
3936{ 4004{
3937 struct trace_parser parser; 4005 struct trace_parser parser;
3938 ssize_t read, ret; 4006 ssize_t read, ret = 0;
4007 struct ftrace_graph_data *fgd = file->private_data;
3939 4008
3940 if (!cnt) 4009 if (!cnt)
3941 return 0; 4010 return 0;
3942 4011
3943 mutex_lock(&graph_lock); 4012 if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX))
3944 4013 return -ENOMEM;
3945 if (trace_parser_get_init(&parser, FTRACE_BUFF_MAX)) {
3946 ret = -ENOMEM;
3947 goto out_unlock;
3948 }
3949 4014
3950 read = trace_get_user(&parser, ubuf, cnt, ppos); 4015 read = trace_get_user(&parser, ubuf, cnt, ppos);
3951 4016
3952 if (read >= 0 && trace_parser_loaded((&parser))) { 4017 if (read >= 0 && trace_parser_loaded((&parser))) {
3953 parser.buffer[parser.idx] = 0; 4018 parser.buffer[parser.idx] = 0;
3954 4019
4020 mutex_lock(&graph_lock);
4021
3955 /* we allow only one expression at a time */ 4022 /* we allow only one expression at a time */
3956 ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, 4023 ret = ftrace_set_func(fgd->table, fgd->count, fgd->size,
3957 parser.buffer); 4024 parser.buffer);
3958 if (ret) 4025
3959 goto out_free; 4026 mutex_unlock(&graph_lock);
3960 } 4027 }
3961 4028
3962 ret = read; 4029 if (!ret)
4030 ret = read;
3963 4031
3964out_free:
3965 trace_parser_put(&parser); 4032 trace_parser_put(&parser);
3966out_unlock:
3967 mutex_unlock(&graph_lock);
3968 4033
3969 return ret; 4034 return ret;
3970} 4035}
@@ -3976,6 +4041,14 @@ static const struct file_operations ftrace_graph_fops = {
3976 .llseek = ftrace_filter_lseek, 4041 .llseek = ftrace_filter_lseek,
3977 .release = ftrace_graph_release, 4042 .release = ftrace_graph_release,
3978}; 4043};
4044
4045static const struct file_operations ftrace_graph_notrace_fops = {
4046 .open = ftrace_graph_notrace_open,
4047 .read = seq_read,
4048 .write = ftrace_graph_write,
4049 .llseek = ftrace_filter_lseek,
4050 .release = ftrace_graph_release,
4051};
3979#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 4052#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
3980 4053
3981static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer) 4054static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
@@ -3997,6 +4070,9 @@ static __init int ftrace_init_dyn_debugfs(struct dentry *d_tracer)
3997 trace_create_file("set_graph_function", 0444, d_tracer, 4070 trace_create_file("set_graph_function", 0444, d_tracer,
3998 NULL, 4071 NULL,
3999 &ftrace_graph_fops); 4072 &ftrace_graph_fops);
4073 trace_create_file("set_graph_notrace", 0444, d_tracer,
4074 NULL,
4075 &ftrace_graph_notrace_fops);
4000#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 4076#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
4001 4077
4002 return 0; 4078 return 0;
@@ -4320,12 +4396,21 @@ ftrace_ops_control_func(unsigned long ip, unsigned long parent_ip,
4320 */ 4396 */
4321 preempt_disable_notrace(); 4397 preempt_disable_notrace();
4322 trace_recursion_set(TRACE_CONTROL_BIT); 4398 trace_recursion_set(TRACE_CONTROL_BIT);
4399
4400 /*
4401 * Control funcs (perf) uses RCU. Only trace if
4402 * RCU is currently active.
4403 */
4404 if (!rcu_is_watching())
4405 goto out;
4406
4323 do_for_each_ftrace_op(op, ftrace_control_list) { 4407 do_for_each_ftrace_op(op, ftrace_control_list) {
4324 if (!(op->flags & FTRACE_OPS_FL_STUB) && 4408 if (!(op->flags & FTRACE_OPS_FL_STUB) &&
4325 !ftrace_function_local_disabled(op) && 4409 !ftrace_function_local_disabled(op) &&
4326 ftrace_ops_test(op, ip, regs)) 4410 ftrace_ops_test(op, ip, regs))
4327 op->func(ip, parent_ip, op, regs); 4411 op->func(ip, parent_ip, op, regs);
4328 } while_for_each_ftrace_op(op); 4412 } while_for_each_ftrace_op(op);
4413 out:
4329 trace_recursion_clear(TRACE_CONTROL_BIT); 4414 trace_recursion_clear(TRACE_CONTROL_BIT);
4330 preempt_enable_notrace(); 4415 preempt_enable_notrace();
4331} 4416}