aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2014-02-10 23:38:46 -0500
committerSteven Rostedt <rostedt@goodmis.org>2014-02-20 12:32:54 -0500
commite1e232ca6b8faa210e5509f17d55519b4392524f (patch)
treeb3666a291ab4a5dba1cf08ba058fcda904ef7591 /kernel/trace
parent43fe98913c9f67e3b523615ee3316f9520a623e0 (diff)
tracing: Add trace_clock=<clock> kernel parameter
Being able to change the trace clock at boot can be advantageous if you need a better source of when things happen across CPUs. The default trace clock is the fastest, but it uses local clocks which may not be synced across CPUs and it does not let you know when events took place with respect to events on other CPUs. The global trace clock can help in this case, and if you do not care about timings, the counter "clock" is the best, as that is just a simple atomic counter that is incremented for every event. Usage is to add "trace_clock=counter" on the kernel command line. You can replace counter with "global" or any of the clocks listed in /sys/kernel/debug/tracing/trace_clock Suggested-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Appreciated-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace.c61
1 files changed, 45 insertions, 16 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index d95ec2876bbb..c90f55d80f86 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -181,6 +181,17 @@ static int __init set_trace_boot_options(char *str)
181} 181}
182__setup("trace_options=", set_trace_boot_options); 182__setup("trace_options=", set_trace_boot_options);
183 183
184static char trace_boot_clock_buf[MAX_TRACER_SIZE] __initdata;
185static char *trace_boot_clock __initdata;
186
187static int __init set_trace_boot_clock(char *str)
188{
189 strlcpy(trace_boot_clock_buf, str, MAX_TRACER_SIZE);
190 trace_boot_clock = trace_boot_clock_buf;
191 return 0;
192}
193__setup("trace_clock=", set_trace_boot_clock);
194
184 195
185unsigned long long ns2usecs(cycle_t nsec) 196unsigned long long ns2usecs(cycle_t nsec)
186{ 197{
@@ -4746,25 +4757,10 @@ static int tracing_clock_show(struct seq_file *m, void *v)
4746 return 0; 4757 return 0;
4747} 4758}
4748 4759
4749static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf, 4760static int tracing_set_clock(struct trace_array *tr, const char *clockstr)
4750 size_t cnt, loff_t *fpos)
4751{ 4761{
4752 struct seq_file *m = filp->private_data;
4753 struct trace_array *tr = m->private;
4754 char buf[64];
4755 const char *clockstr;
4756 int i; 4762 int i;
4757 4763
4758 if (cnt >= sizeof(buf))
4759 return -EINVAL;
4760
4761 if (copy_from_user(&buf, ubuf, cnt))
4762 return -EFAULT;
4763
4764 buf[cnt] = 0;
4765
4766 clockstr = strstrip(buf);
4767
4768 for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) { 4764 for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) {
4769 if (strcmp(trace_clocks[i].name, clockstr) == 0) 4765 if (strcmp(trace_clocks[i].name, clockstr) == 0)
4770 break; 4766 break;
@@ -4792,6 +4788,32 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
4792 4788
4793 mutex_unlock(&trace_types_lock); 4789 mutex_unlock(&trace_types_lock);
4794 4790
4791 return 0;
4792}
4793
4794static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
4795 size_t cnt, loff_t *fpos)
4796{
4797 struct seq_file *m = filp->private_data;
4798 struct trace_array *tr = m->private;
4799 char buf[64];
4800 const char *clockstr;
4801 int ret;
4802
4803 if (cnt >= sizeof(buf))
4804 return -EINVAL;
4805
4806 if (copy_from_user(&buf, ubuf, cnt))
4807 return -EFAULT;
4808
4809 buf[cnt] = 0;
4810
4811 clockstr = strstrip(buf);
4812
4813 ret = tracing_set_clock(tr, clockstr);
4814 if (ret)
4815 return ret;
4816
4795 *fpos += cnt; 4817 *fpos += cnt;
4796 4818
4797 return cnt; 4819 return cnt;
@@ -6574,6 +6596,13 @@ __init static int tracer_alloc_buffers(void)
6574 6596
6575 trace_init_cmdlines(); 6597 trace_init_cmdlines();
6576 6598
6599 if (trace_boot_clock) {
6600 ret = tracing_set_clock(&global_trace, trace_boot_clock);
6601 if (ret < 0)
6602 pr_warning("Trace clock %s not defined, going back to default\n",
6603 trace_boot_clock);
6604 }
6605
6577 /* 6606 /*
6578 * register_tracer() might reference current_trace, so it 6607 * register_tracer() might reference current_trace, so it
6579 * needs to be set before we register anything. This is 6608 * needs to be set before we register anything. This is