Skip to content

Commit

Permalink
tracing: Add trace_clock=<clock> kernel parameter
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Steven Rostedt committed Feb 20, 2014
1 parent 43fe989 commit e1e232c
Showing 1 changed file with 45 additions and 16 deletions.
61 changes: 45 additions & 16 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,17 @@ static int __init set_trace_boot_options(char *str)
}
__setup("trace_options=", set_trace_boot_options);

static char trace_boot_clock_buf[MAX_TRACER_SIZE] __initdata;
static char *trace_boot_clock __initdata;

static int __init set_trace_boot_clock(char *str)
{
strlcpy(trace_boot_clock_buf, str, MAX_TRACER_SIZE);
trace_boot_clock = trace_boot_clock_buf;
return 0;
}
__setup("trace_clock=", set_trace_boot_clock);


unsigned long long ns2usecs(cycle_t nsec)
{
Expand Down Expand Up @@ -4746,25 +4757,10 @@ static int tracing_clock_show(struct seq_file *m, void *v)
return 0;
}

static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *fpos)
static int tracing_set_clock(struct trace_array *tr, const char *clockstr)
{
struct seq_file *m = filp->private_data;
struct trace_array *tr = m->private;
char buf[64];
const char *clockstr;
int i;

if (cnt >= sizeof(buf))
return -EINVAL;

if (copy_from_user(&buf, ubuf, cnt))
return -EFAULT;

buf[cnt] = 0;

clockstr = strstrip(buf);

for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) {
if (strcmp(trace_clocks[i].name, clockstr) == 0)
break;
Expand Down Expand Up @@ -4792,6 +4788,32 @@ static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,

mutex_unlock(&trace_types_lock);

return 0;
}

static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *fpos)
{
struct seq_file *m = filp->private_data;
struct trace_array *tr = m->private;
char buf[64];
const char *clockstr;
int ret;

if (cnt >= sizeof(buf))
return -EINVAL;

if (copy_from_user(&buf, ubuf, cnt))
return -EFAULT;

buf[cnt] = 0;

clockstr = strstrip(buf);

ret = tracing_set_clock(tr, clockstr);
if (ret)
return ret;

*fpos += cnt;

return cnt;
Expand Down Expand Up @@ -6574,6 +6596,13 @@ __init static int tracer_alloc_buffers(void)

trace_init_cmdlines();

if (trace_boot_clock) {
ret = tracing_set_clock(&global_trace, trace_boot_clock);
if (ret < 0)
pr_warning("Trace clock %s not defined, going back to default\n",
trace_boot_clock);
}

/*
* register_tracer() might reference current_trace, so it
* needs to be set before we register anything. This is
Expand Down

0 comments on commit e1e232c

Please sign in to comment.