aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ring_buffer.h3
-rw-r--r--kernel/trace/ftrace.c8
-rw-r--r--kernel/trace/ring_buffer.c101
3 files changed, 106 insertions, 6 deletions
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index 536b0ca46a03..e097c2e6b6dc 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -120,6 +120,9 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
120u64 ring_buffer_time_stamp(int cpu); 120u64 ring_buffer_time_stamp(int cpu);
121void ring_buffer_normalize_time_stamp(int cpu, u64 *ts); 121void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);
122 122
123void tracing_on(void);
124void tracing_off(void);
125
123enum ring_buffer_flags { 126enum ring_buffer_flags {
124 RB_FL_OVERWRITE = 1 << 0, 127 RB_FL_OVERWRITE = 1 << 0,
125}; 128};
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 4a39d24568c8..14fa52297b28 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -185,7 +185,6 @@ enum {
185}; 185};
186 186
187static int ftrace_filtered; 187static int ftrace_filtered;
188static int tracing_on;
189 188
190static LIST_HEAD(ftrace_new_addrs); 189static LIST_HEAD(ftrace_new_addrs);
191 190
@@ -506,13 +505,10 @@ static int __ftrace_modify_code(void *data)
506{ 505{
507 int *command = data; 506 int *command = data;
508 507
509 if (*command & FTRACE_ENABLE_CALLS) { 508 if (*command & FTRACE_ENABLE_CALLS)
510 ftrace_replace_code(1); 509 ftrace_replace_code(1);
511 tracing_on = 1; 510 else if (*command & FTRACE_DISABLE_CALLS)
512 } else if (*command & FTRACE_DISABLE_CALLS) {
513 ftrace_replace_code(0); 511 ftrace_replace_code(0);
514 tracing_on = 0;
515 }
516 512
517 if (*command & FTRACE_UPDATE_TRACE_FUNC) 513 if (*command & FTRACE_UPDATE_TRACE_FUNC)
518 ftrace_update_ftrace_func(ftrace_trace_function); 514 ftrace_update_ftrace_func(ftrace_trace_function);
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 2f76193c3489..b08ee9f00c8d 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -16,6 +16,35 @@
16#include <linux/list.h> 16#include <linux/list.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18 18
19#include "trace.h"
20
21/* Global flag to disable all recording to ring buffers */
22static int ring_buffers_off __read_mostly;
23
24/**
25 * tracing_on - enable all tracing buffers
26 *
27 * This function enables all tracing buffers that may have been
28 * disabled with tracing_off.
29 */
30void tracing_on(void)
31{
32 ring_buffers_off = 0;
33}
34
35/**
36 * tracing_off - turn off all tracing buffers
37 *
38 * This function stops all tracing buffers from recording data.
39 * It does not disable any overhead the tracers themselves may
40 * be causing. This function simply causes all recording to
41 * the ring buffers to fail.
42 */
43void tracing_off(void)
44{
45 ring_buffers_off = 1;
46}
47
19/* Up this if you want to test the TIME_EXTENTS and normalization */ 48/* Up this if you want to test the TIME_EXTENTS and normalization */
20#define DEBUG_SHIFT 0 49#define DEBUG_SHIFT 0
21 50
@@ -1133,6 +1162,9 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer,
1133 struct ring_buffer_event *event; 1162 struct ring_buffer_event *event;
1134 int cpu, resched; 1163 int cpu, resched;
1135 1164
1165 if (ring_buffers_off)
1166 return NULL;
1167
1136 if (atomic_read(&buffer->record_disabled)) 1168 if (atomic_read(&buffer->record_disabled))
1137 return NULL; 1169 return NULL;
1138 1170
@@ -1249,6 +1281,9 @@ int ring_buffer_write(struct ring_buffer *buffer,
1249 int ret = -EBUSY; 1281 int ret = -EBUSY;
1250 int cpu, resched; 1282 int cpu, resched;
1251 1283
1284 if (ring_buffers_off)
1285 return -EBUSY;
1286
1252 if (atomic_read(&buffer->record_disabled)) 1287 if (atomic_read(&buffer->record_disabled))
1253 return -EBUSY; 1288 return -EBUSY;
1254 1289
@@ -2070,3 +2105,69 @@ int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
2070 return 0; 2105 return 0;
2071} 2106}
2072 2107
2108static ssize_t
2109rb_simple_read(struct file *filp, char __user *ubuf,
2110 size_t cnt, loff_t *ppos)
2111{
2112 int *p = filp->private_data;
2113 char buf[64];
2114 int r;
2115
2116 /* !ring_buffers_off == tracing_on */
2117 r = sprintf(buf, "%d\n", !*p);
2118
2119 return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
2120}
2121
2122static ssize_t
2123rb_simple_write(struct file *filp, const char __user *ubuf,
2124 size_t cnt, loff_t *ppos)
2125{
2126 int *p = filp->private_data;
2127 char buf[64];
2128 long val;
2129 int ret;
2130
2131 if (cnt >= sizeof(buf))
2132 return -EINVAL;
2133
2134 if (copy_from_user(&buf, ubuf, cnt))
2135 return -EFAULT;
2136
2137 buf[cnt] = 0;
2138
2139 ret = strict_strtoul(buf, 10, &val);
2140 if (ret < 0)
2141 return ret;
2142
2143 /* !ring_buffers_off == tracing_on */
2144 *p = !val;
2145
2146 (*ppos)++;
2147
2148 return cnt;
2149}
2150
2151static struct file_operations rb_simple_fops = {
2152 .open = tracing_open_generic,
2153 .read = rb_simple_read,
2154 .write = rb_simple_write,
2155};
2156
2157
2158static __init int rb_init_debugfs(void)
2159{
2160 struct dentry *d_tracer;
2161 struct dentry *entry;
2162
2163 d_tracer = tracing_init_dentry();
2164
2165 entry = debugfs_create_file("tracing_on", 0644, d_tracer,
2166 &ring_buffers_off, &rb_simple_fops);
2167 if (!entry)
2168 pr_warning("Could not create debugfs 'tracing_on' entry\n");
2169
2170 return 0;
2171}
2172
2173fs_initcall(rb_init_debugfs);