aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung.kim@lge.com>2013-10-14 04:24:24 -0400
committerSteven Rostedt <rostedt@goodmis.org>2013-10-18 22:17:51 -0400
commitfaf982a60f7c985808f761cff5d508f21c691790 (patch)
treef74dd11f75d6eb77b9ba2302235dd62760c020bc /kernel
parent9aa72b4bf823b7b439fbba95fa84abee3b9d6d79 (diff)
ftrace: Introduce struct ftrace_graph_data
The struct ftrace_graph_data is for generalizing the access to set_graph_function file. This is a preparation for adding support to set_graph_notrace. Link: http://lkml.kernel.org/r/1381739066-7531-3-git-send-email-namhyung@kernel.org Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/ftrace.c81
1 files changed, 62 insertions, 19 deletions
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a77e4a0142ee..0ff3449b4272 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -3641,7 +3641,7 @@ __setup("ftrace_filter=", set_ftrace_filter);
3641 3641
3642#ifdef CONFIG_FUNCTION_GRAPH_TRACER 3642#ifdef CONFIG_FUNCTION_GRAPH_TRACER
3643static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; 3643static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
3644static int ftrace_set_func(unsigned long *array, int *idx, char *buffer); 3644static int ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer);
3645 3645
3646static int __init set_graph_function(char *str) 3646static int __init set_graph_function(char *str)
3647{ 3647{
@@ -3659,7 +3659,7 @@ static void __init set_ftrace_early_graph(char *buf)
3659 func = strsep(&buf, ","); 3659 func = strsep(&buf, ",");
3660 /* we allow only one expression at a time */ 3660 /* we allow only one expression at a time */
3661 ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, 3661 ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count,
3662 func); 3662 FTRACE_GRAPH_MAX_FUNCS, func);
3663 if (ret) 3663 if (ret)
3664 printk(KERN_DEBUG "ftrace: function %s not " 3664 printk(KERN_DEBUG "ftrace: function %s not "
3665 "traceable\n", func); 3665 "traceable\n", func);
@@ -3778,12 +3778,21 @@ static DEFINE_MUTEX(graph_lock);
3778int ftrace_graph_count; 3778int ftrace_graph_count;
3779unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; 3779unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly;
3780 3780
3781struct ftrace_graph_data {
3782 unsigned long *table;
3783 size_t size;
3784 int *count;
3785 const struct seq_operations *seq_ops;
3786};
3787
3781static void * 3788static void *
3782__g_next(struct seq_file *m, loff_t *pos) 3789__g_next(struct seq_file *m, loff_t *pos)
3783{ 3790{
3784 if (*pos >= ftrace_graph_count) 3791 struct ftrace_graph_data *fgd = m->private;
3792
3793 if (*pos >= *fgd->count)
3785 return NULL; 3794 return NULL;
3786 return &ftrace_graph_funcs[*pos]; 3795 return &fgd->table[*pos];
3787} 3796}
3788 3797
3789static void * 3798static void *
@@ -3795,10 +3804,12 @@ g_next(struct seq_file *m, void *v, loff_t *pos)
3795 3804
3796static void *g_start(struct seq_file *m, loff_t *pos) 3805static void *g_start(struct seq_file *m, loff_t *pos)
3797{ 3806{
3807 struct ftrace_graph_data *fgd = m->private;
3808
3798 mutex_lock(&graph_lock); 3809 mutex_lock(&graph_lock);
3799 3810
3800 /* Nothing, tell g_show to print all functions are enabled */ 3811 /* Nothing, tell g_show to print all functions are enabled */
3801 if (!ftrace_graph_count && !*pos) 3812 if (!*fgd->count && !*pos)
3802 return (void *)1; 3813 return (void *)1;
3803 3814
3804 return __g_next(m, pos); 3815 return __g_next(m, pos);
@@ -3834,37 +3845,68 @@ static const struct seq_operations ftrace_graph_seq_ops = {
3834}; 3845};
3835 3846
3836static int 3847static int
3837ftrace_graph_open(struct inode *inode, struct file *file) 3848__ftrace_graph_open(struct inode *inode, struct file *file,
3849 struct ftrace_graph_data *fgd)
3838{ 3850{
3839 int ret = 0; 3851 int ret = 0;
3840 3852
3841 if (unlikely(ftrace_disabled))
3842 return -ENODEV;
3843
3844 mutex_lock(&graph_lock); 3853 mutex_lock(&graph_lock);
3845 if ((file->f_mode & FMODE_WRITE) && 3854 if ((file->f_mode & FMODE_WRITE) &&
3846 (file->f_flags & O_TRUNC)) { 3855 (file->f_flags & O_TRUNC)) {
3847 ftrace_graph_count = 0; 3856 *fgd->count = 0;
3848 memset(ftrace_graph_funcs, 0, sizeof(ftrace_graph_funcs)); 3857 memset(fgd->table, 0, fgd->size * sizeof(*fgd->table));
3849 } 3858 }
3850 mutex_unlock(&graph_lock); 3859 mutex_unlock(&graph_lock);
3851 3860
3852 if (file->f_mode & FMODE_READ) 3861 if (file->f_mode & FMODE_READ) {
3853 ret = seq_open(file, &ftrace_graph_seq_ops); 3862 ret = seq_open(file, fgd->seq_ops);
3863 if (!ret) {
3864 struct seq_file *m = file->private_data;
3865 m->private = fgd;
3866 }
3867 } else
3868 file->private_data = fgd;
3854 3869
3855 return ret; 3870 return ret;
3856} 3871}
3857 3872
3858static int 3873static int
3874ftrace_graph_open(struct inode *inode, struct file *file)
3875{
3876 struct ftrace_graph_data *fgd;
3877
3878 if (unlikely(ftrace_disabled))
3879 return -ENODEV;
3880
3881 fgd = kmalloc(sizeof(*fgd), GFP_KERNEL);
3882 if (fgd == NULL)
3883 return -ENOMEM;
3884
3885 fgd->table = ftrace_graph_funcs;
3886 fgd->size = FTRACE_GRAPH_MAX_FUNCS;
3887 fgd->count = &ftrace_graph_count;
3888 fgd->seq_ops = &ftrace_graph_seq_ops;
3889
3890 return __ftrace_graph_open(inode, file, fgd);
3891}
3892
3893static int
3859ftrace_graph_release(struct inode *inode, struct file *file) 3894ftrace_graph_release(struct inode *inode, struct file *file)
3860{ 3895{
3861 if (file->f_mode & FMODE_READ) 3896 if (file->f_mode & FMODE_READ) {
3897 struct seq_file *m = file->private_data;
3898
3899 kfree(m->private);
3862 seq_release(inode, file); 3900 seq_release(inode, file);
3901 } else {
3902 kfree(file->private_data);
3903 }
3904
3863 return 0; 3905 return 0;
3864} 3906}
3865 3907
3866static int 3908static int
3867ftrace_set_func(unsigned long *array, int *idx, char *buffer) 3909ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
3868{ 3910{
3869 struct dyn_ftrace *rec; 3911 struct dyn_ftrace *rec;
3870 struct ftrace_page *pg; 3912 struct ftrace_page *pg;
@@ -3877,7 +3919,7 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
3877 3919
3878 /* decode regex */ 3920 /* decode regex */
3879 type = filter_parse_regex(buffer, strlen(buffer), &search, &not); 3921 type = filter_parse_regex(buffer, strlen(buffer), &search, &not);
3880 if (!not && *idx >= FTRACE_GRAPH_MAX_FUNCS) 3922 if (!not && *idx >= size)
3881 return -EBUSY; 3923 return -EBUSY;
3882 3924
3883 search_len = strlen(search); 3925 search_len = strlen(search);
@@ -3905,7 +3947,7 @@ ftrace_set_func(unsigned long *array, int *idx, char *buffer)
3905 fail = 0; 3947 fail = 0;
3906 if (!exists) { 3948 if (!exists) {
3907 array[(*idx)++] = rec->ip; 3949 array[(*idx)++] = rec->ip;
3908 if (*idx >= FTRACE_GRAPH_MAX_FUNCS) 3950 if (*idx >= size)
3909 goto out; 3951 goto out;
3910 } 3952 }
3911 } else { 3953 } else {
@@ -3932,6 +3974,7 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
3932{ 3974{
3933 struct trace_parser parser; 3975 struct trace_parser parser;
3934 ssize_t read, ret; 3976 ssize_t read, ret;
3977 struct ftrace_graph_data *fgd = file->private_data;
3935 3978
3936 if (!cnt) 3979 if (!cnt)
3937 return 0; 3980 return 0;
@@ -3949,8 +3992,8 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
3949 parser.buffer[parser.idx] = 0; 3992 parser.buffer[parser.idx] = 0;
3950 3993
3951 /* we allow only one expression at a time */ 3994 /* we allow only one expression at a time */
3952 ret = ftrace_set_func(ftrace_graph_funcs, &ftrace_graph_count, 3995 ret = ftrace_set_func(fgd->table, fgd->count, fgd->size,
3953 parser.buffer); 3996 parser.buffer);
3954 if (ret) 3997 if (ret)
3955 goto out_free; 3998 goto out_free;
3956 } 3999 }