aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
authorPekka Paalanen <pq@iki.fi>2008-09-16 15:06:42 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-14 04:37:20 -0400
commit5bf9a1ee350a10feb94107de32a203d81fbbe706 (patch)
treeac6b11aaa35194aed9fe9f1403c9542d070d0c62 /kernel/trace/trace.c
parent4427414170a63331a9cc36b9598502c5cdfe453b (diff)
ftrace: inject markers via trace_marker file
Allow a user to inject a marker (TRACE_PRINT entry) into the trace ring buffer. The related file operations are derived from code by Frédéric Weisbecker <fweisbec@gmail.com>. Signed-off-by: Pekka Paalanen <pq@iki.fi> Acked-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c76
1 files changed, 71 insertions, 5 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 7e7154f77009..eee1fd964898 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -2879,6 +2879,66 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
2879 return cnt; 2879 return cnt;
2880} 2880}
2881 2881
2882static int tracing_open_mark(struct inode *inode, struct file *filp)
2883{
2884 int ret;
2885
2886 ret = tracing_open_generic(inode, filp);
2887 if (ret)
2888 return ret;
2889
2890 if (current_trace == &no_tracer)
2891 return -ENODEV;
2892
2893 return 0;
2894}
2895
2896static int mark_printk(const char *fmt, ...)
2897{
2898 int ret;
2899 va_list args;
2900 va_start(args, fmt);
2901 ret = trace_vprintk(0, fmt, args);
2902 va_end(args);
2903 return ret;
2904}
2905
2906static ssize_t
2907tracing_mark_write(struct file *filp, const char __user *ubuf,
2908 size_t cnt, loff_t *fpos)
2909{
2910 char *buf;
2911 char *end;
2912 struct trace_array *tr = &global_trace;
2913
2914 if (current_trace == &no_tracer || !tr->ctrl || tracing_disabled)
2915 return -EINVAL;
2916
2917 if (cnt > TRACE_BUF_SIZE)
2918 cnt = TRACE_BUF_SIZE;
2919
2920 buf = kmalloc(cnt + 1, GFP_KERNEL);
2921 if (buf == NULL)
2922 return -ENOMEM;
2923
2924 if (copy_from_user(buf, ubuf, cnt)) {
2925 kfree(buf);
2926 return -EFAULT;
2927 }
2928
2929 /* Cut from the first nil or newline. */
2930 buf[cnt] = '\0';
2931 end = strchr(buf, '\n');
2932 if (end)
2933 *end = '\0';
2934
2935 cnt = mark_printk("%s\n", buf);
2936 kfree(buf);
2937 *fpos += cnt;
2938
2939 return cnt;
2940}
2941
2882static struct file_operations tracing_max_lat_fops = { 2942static struct file_operations tracing_max_lat_fops = {
2883 .open = tracing_open_generic, 2943 .open = tracing_open_generic,
2884 .read = tracing_max_lat_read, 2944 .read = tracing_max_lat_read,
@@ -2910,6 +2970,11 @@ static struct file_operations tracing_entries_fops = {
2910 .write = tracing_entries_write, 2970 .write = tracing_entries_write,
2911}; 2971};
2912 2972
2973static struct file_operations tracing_mark_fops = {
2974 .open = tracing_open_mark,
2975 .write = tracing_mark_write,
2976};
2977
2913#ifdef CONFIG_DYNAMIC_FTRACE 2978#ifdef CONFIG_DYNAMIC_FTRACE
2914 2979
2915static ssize_t 2980static ssize_t
@@ -3027,6 +3092,12 @@ static __init void tracer_init_debugfs(void)
3027 pr_warning("Could not create debugfs " 3092 pr_warning("Could not create debugfs "
3028 "'trace_entries' entry\n"); 3093 "'trace_entries' entry\n");
3029 3094
3095 entry = debugfs_create_file("trace_marker", 0220, d_tracer,
3096 NULL, &tracing_mark_fops);
3097 if (!entry)
3098 pr_warning("Could not create debugfs "
3099 "'trace_marker' entry\n");
3100
3030#ifdef CONFIG_DYNAMIC_FTRACE 3101#ifdef CONFIG_DYNAMIC_FTRACE
3031 entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer, 3102 entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer,
3032 &ftrace_update_tot_cnt, 3103 &ftrace_update_tot_cnt,
@@ -3040,11 +3111,6 @@ static __init void tracer_init_debugfs(void)
3040#endif 3111#endif
3041} 3112}
3042 3113
3043#define TRACE_BUF_SIZE 1024
3044#define TRACE_PRINT_BUF_SIZE \
3045 (sizeof(struct trace_field) - offsetof(struct trace_field, print.buf))
3046#define TRACE_CONT_BUF_SIZE sizeof(struct trace_field)
3047
3048int trace_vprintk(unsigned long ip, const char *fmt, va_list args) 3114int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
3049{ 3115{
3050 static DEFINE_SPINLOCK(trace_buf_lock); 3116 static DEFINE_SPINLOCK(trace_buf_lock);