aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c92
1 files changed, 75 insertions, 17 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8ac204360a39..63dbc7ff213f 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -323,12 +323,21 @@ static const char *trace_options[] = {
323 "printk-msg-only", 323 "printk-msg-only",
324 "context-info", 324 "context-info",
325 "latency-format", 325 "latency-format",
326 "global-clock",
327 "sleep-time", 326 "sleep-time",
328 "graph-time", 327 "graph-time",
329 NULL 328 NULL
330}; 329};
331 330
331static struct {
332 u64 (*func)(void);
333 const char *name;
334} trace_clocks[] = {
335 { trace_clock_local, "local" },
336 { trace_clock_global, "global" },
337};
338
339int trace_clock_id;
340
332/* 341/*
333 * ftrace_max_lock is used to protect the swapping of buffers 342 * ftrace_max_lock is used to protect the swapping of buffers
334 * when taking a max snapshot. The buffers themselves are 343 * when taking a max snapshot. The buffers themselves are
@@ -2159,22 +2168,6 @@ static void set_tracer_flags(unsigned int mask, int enabled)
2159 trace_flags |= mask; 2168 trace_flags |= mask;
2160 else 2169 else
2161 trace_flags &= ~mask; 2170 trace_flags &= ~mask;
2162
2163 if (mask == TRACE_ITER_GLOBAL_CLK) {
2164 u64 (*func)(void);
2165
2166 if (enabled)
2167 func = trace_clock_global;
2168 else
2169 func = trace_clock_local;
2170
2171 mutex_lock(&trace_types_lock);
2172 ring_buffer_set_clock(global_trace.buffer, func);
2173
2174 if (max_tr.buffer)
2175 ring_buffer_set_clock(max_tr.buffer, func);
2176 mutex_unlock(&trace_types_lock);
2177 }
2178} 2171}
2179 2172
2180static ssize_t 2173static ssize_t
@@ -3142,6 +3135,62 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
3142 return cnt; 3135 return cnt;
3143} 3136}
3144 3137
3138static ssize_t tracing_clock_read(struct file *filp, char __user *ubuf,
3139 size_t cnt, loff_t *ppos)
3140{
3141 char buf[64];
3142 int bufiter = 0;
3143 int i;
3144
3145 for (i = 0; i < ARRAY_SIZE(trace_clocks); i++)
3146 bufiter += snprintf(buf + bufiter, sizeof(buf) - bufiter,
3147 "%s%s%s%s", i ? " " : "",
3148 i == trace_clock_id ? "[" : "", trace_clocks[i].name,
3149 i == trace_clock_id ? "]" : "");
3150 bufiter += snprintf(buf + bufiter, sizeof(buf) - bufiter, "\n");
3151
3152 return simple_read_from_buffer(ubuf, cnt, ppos, buf, bufiter);
3153}
3154
3155static ssize_t tracing_clock_write(struct file *filp, const char __user *ubuf,
3156 size_t cnt, loff_t *fpos)
3157{
3158 char buf[64];
3159 const char *clockstr;
3160 int i;
3161
3162 if (cnt >= sizeof(buf))
3163 return -EINVAL;
3164
3165 if (copy_from_user(&buf, ubuf, cnt))
3166 return -EFAULT;
3167
3168 buf[cnt] = 0;
3169
3170 clockstr = strstrip(buf);
3171
3172 for (i = 0; i < ARRAY_SIZE(trace_clocks); i++) {
3173 if (strcmp(trace_clocks[i].name, clockstr) == 0)
3174 break;
3175 }
3176 if (i == ARRAY_SIZE(trace_clocks))
3177 return -EINVAL;
3178
3179 trace_clock_id = i;
3180
3181 mutex_lock(&trace_types_lock);
3182
3183 ring_buffer_set_clock(global_trace.buffer, trace_clocks[i].func);
3184 if (max_tr.buffer)
3185 ring_buffer_set_clock(max_tr.buffer, trace_clocks[i].func);
3186
3187 mutex_unlock(&trace_types_lock);
3188
3189 *fpos += cnt;
3190
3191 return cnt;
3192}
3193
3145static const struct file_operations tracing_max_lat_fops = { 3194static const struct file_operations tracing_max_lat_fops = {
3146 .open = tracing_open_generic, 3195 .open = tracing_open_generic,
3147 .read = tracing_max_lat_read, 3196 .read = tracing_max_lat_read,
@@ -3179,6 +3228,12 @@ static const struct file_operations tracing_mark_fops = {
3179 .write = tracing_mark_write, 3228 .write = tracing_mark_write,
3180}; 3229};
3181 3230
3231static const struct file_operations trace_clock_fops = {
3232 .open = tracing_open_generic,
3233 .read = tracing_clock_read,
3234 .write = tracing_clock_write,
3235};
3236
3182struct ftrace_buffer_info { 3237struct ftrace_buffer_info {
3183 struct trace_array *tr; 3238 struct trace_array *tr;
3184 void *spare; 3239 void *spare;
@@ -3918,6 +3973,9 @@ static __init int tracer_init_debugfs(void)
3918 trace_create_file("saved_cmdlines", 0444, d_tracer, 3973 trace_create_file("saved_cmdlines", 0444, d_tracer,
3919 NULL, &tracing_saved_cmdlines_fops); 3974 NULL, &tracing_saved_cmdlines_fops);
3920 3975
3976 trace_create_file("trace_clock", 0644, d_tracer, NULL,
3977 &trace_clock_fops);
3978
3921#ifdef CONFIG_DYNAMIC_FTRACE 3979#ifdef CONFIG_DYNAMIC_FTRACE
3922 trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, 3980 trace_create_file("dyn_ftrace_total_info", 0444, d_tracer,
3923 &ftrace_update_tot_cnt, &tracing_dyn_info_fops); 3981 &ftrace_update_tot_cnt, &tracing_dyn_info_fops);