]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
ftrace: inject markers via trace_marker file
authorPekka Paalanen <pq@iki.fi>
Tue, 16 Sep 2008 19:06:42 +0000 (22:06 +0300)
committerIngo Molnar <mingo@elte.hu>
Tue, 14 Oct 2008 08:37:20 +0000 (10:37 +0200)
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>
Documentation/tracers/mmiotrace.txt
kernel/trace/trace.c
kernel/trace/trace.h

index a4afb560a45bfa9c7429f18d54d0f8b4c194b116..5bbbe2096223f69bc1f0d7007f6d07a3385e4fd4 100644 (file)
@@ -36,7 +36,7 @@ $ mount -t debugfs debugfs /debug
 $ echo mmiotrace > /debug/tracing/current_tracer
 $ cat /debug/tracing/trace_pipe > mydump.txt &
 Start X or whatever.
-$ echo "X is up" > /debug/tracing/marker
+$ echo "X is up" > /debug/tracing/trace_marker
 $ echo none > /debug/tracing/current_tracer
 Check for lost events.
 
@@ -59,9 +59,8 @@ The 'cat' process should stay running (sleeping) in the background.
 Load the driver you want to trace and use it. Mmiotrace will only catch MMIO
 accesses to areas that are ioremapped while mmiotrace is active.
 
-[Unimplemented feature:]
 During tracing you can place comments (markers) into the trace by
-$ echo "X is up" > /debug/tracing/marker
+$ echo "X is up" > /debug/tracing/trace_marker
 This makes it easier to see which part of the (huge) trace corresponds to
 which action. It is recommended to place descriptive markers about what you
 do.
index 7e7154f77009157a1164c6d72b53e895c80770d9..eee1fd9648986e767bb21c9a89906f57d891f1ba 100644 (file)
@@ -2879,6 +2879,66 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
        return cnt;
 }
 
+static int tracing_open_mark(struct inode *inode, struct file *filp)
+{
+       int ret;
+
+       ret = tracing_open_generic(inode, filp);
+       if (ret)
+               return ret;
+
+       if (current_trace == &no_tracer)
+               return -ENODEV;
+
+       return 0;
+}
+
+static int mark_printk(const char *fmt, ...)
+{
+       int ret;
+       va_list args;
+       va_start(args, fmt);
+       ret = trace_vprintk(0, fmt, args);
+       va_end(args);
+       return ret;
+}
+
+static ssize_t
+tracing_mark_write(struct file *filp, const char __user *ubuf,
+                                       size_t cnt, loff_t *fpos)
+{
+       char *buf;
+       char *end;
+       struct trace_array *tr = &global_trace;
+
+       if (current_trace == &no_tracer || !tr->ctrl || tracing_disabled)
+               return -EINVAL;
+
+       if (cnt > TRACE_BUF_SIZE)
+               cnt = TRACE_BUF_SIZE;
+
+       buf = kmalloc(cnt + 1, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       if (copy_from_user(buf, ubuf, cnt)) {
+               kfree(buf);
+               return -EFAULT;
+       }
+
+       /* Cut from the first nil or newline. */
+       buf[cnt] = '\0';
+       end = strchr(buf, '\n');
+       if (end)
+               *end = '\0';
+
+       cnt = mark_printk("%s\n", buf);
+       kfree(buf);
+       *fpos += cnt;
+
+       return cnt;
+}
+
 static struct file_operations tracing_max_lat_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
@@ -2910,6 +2970,11 @@ static struct file_operations tracing_entries_fops = {
        .write          = tracing_entries_write,
 };
 
+static struct file_operations tracing_mark_fops = {
+       .open           = tracing_open_mark,
+       .write          = tracing_mark_write,
+};
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 static ssize_t
@@ -3027,6 +3092,12 @@ static __init void tracer_init_debugfs(void)
                pr_warning("Could not create debugfs "
                           "'trace_entries' entry\n");
 
+       entry = debugfs_create_file("trace_marker", 0220, d_tracer,
+                                   NULL, &tracing_mark_fops);
+       if (!entry)
+               pr_warning("Could not create debugfs "
+                          "'trace_marker' entry\n");
+
 #ifdef CONFIG_DYNAMIC_FTRACE
        entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer,
                                    &ftrace_update_tot_cnt,
@@ -3040,11 +3111,6 @@ static __init void tracer_init_debugfs(void)
 #endif
 }
 
-#define TRACE_BUF_SIZE 1024
-#define TRACE_PRINT_BUF_SIZE \
-       (sizeof(struct trace_field) - offsetof(struct trace_field, print.buf))
-#define TRACE_CONT_BUF_SIZE sizeof(struct trace_field)
-
 int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
 {
        static DEFINE_SPINLOCK(trace_buf_lock);
index 648433d18ccbdb1886c8ce42164e4bc439b27c4e..42f65d0097f09a31f364424aa40e9f0d1e9d253e 100644 (file)
@@ -124,6 +124,10 @@ struct trace_entry {
 };
 
 #define TRACE_ENTRY_SIZE       sizeof(struct trace_entry)
+#define TRACE_BUF_SIZE         1024
+#define TRACE_PRINT_BUF_SIZE \
+       (sizeof(struct trace_field) - offsetof(struct trace_field, print.buf))
+#define TRACE_CONT_BUF_SIZE    sizeof(struct trace_field)
 
 /*
  * The CPU trace array - it consists of thousands of trace entries