diff options
author | Namhyung Kim <namhyung.kim@lge.com> | 2013-10-14 04:24:24 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2013-10-18 22:17:51 -0400 |
commit | faf982a60f7c985808f761cff5d508f21c691790 (patch) | |
tree | f74dd11f75d6eb77b9ba2302235dd62760c020bc /kernel | |
parent | 9aa72b4bf823b7b439fbba95fa84abee3b9d6d79 (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.c | 81 |
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 |
3643 | static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; | 3643 | static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata; |
3644 | static int ftrace_set_func(unsigned long *array, int *idx, char *buffer); | 3644 | static int ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer); |
3645 | 3645 | ||
3646 | static int __init set_graph_function(char *str) | 3646 | static 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); | |||
3778 | int ftrace_graph_count; | 3778 | int ftrace_graph_count; |
3779 | unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; | 3779 | unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; |
3780 | 3780 | ||
3781 | struct ftrace_graph_data { | ||
3782 | unsigned long *table; | ||
3783 | size_t size; | ||
3784 | int *count; | ||
3785 | const struct seq_operations *seq_ops; | ||
3786 | }; | ||
3787 | |||
3781 | static void * | 3788 | static 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 | ||
3789 | static void * | 3798 | static void * |
@@ -3795,10 +3804,12 @@ g_next(struct seq_file *m, void *v, loff_t *pos) | |||
3795 | 3804 | ||
3796 | static void *g_start(struct seq_file *m, loff_t *pos) | 3805 | static 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 | ||
3836 | static int | 3847 | static int |
3837 | ftrace_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 | ||
3858 | static int | 3873 | static int |
3874 | ftrace_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 | |||
3893 | static int | ||
3859 | ftrace_graph_release(struct inode *inode, struct file *file) | 3894 | ftrace_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 | ||
3866 | static int | 3908 | static int |
3867 | ftrace_set_func(unsigned long *array, int *idx, char *buffer) | 3909 | ftrace_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, ¬); | 3921 | type = filter_parse_regex(buffer, strlen(buffer), &search, ¬); |
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 | } |