diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/ring_buffer.c | 79 |
1 files changed, 66 insertions, 13 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 85ced143c2c4..e206951603c1 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -18,8 +18,46 @@ | |||
18 | 18 | ||
19 | #include "trace.h" | 19 | #include "trace.h" |
20 | 20 | ||
21 | /* Global flag to disable all recording to ring buffers */ | 21 | /* |
22 | static int ring_buffers_off __read_mostly; | 22 | * A fast way to enable or disable all ring buffers is to |
23 | * call tracing_on or tracing_off. Turning off the ring buffers | ||
24 | * prevents all ring buffers from being recorded to. | ||
25 | * Turning this switch on, makes it OK to write to the | ||
26 | * ring buffer, if the ring buffer is enabled itself. | ||
27 | * | ||
28 | * There's three layers that must be on in order to write | ||
29 | * to the ring buffer. | ||
30 | * | ||
31 | * 1) This global flag must be set. | ||
32 | * 2) The ring buffer must be enabled for recording. | ||
33 | * 3) The per cpu buffer must be enabled for recording. | ||
34 | * | ||
35 | * In case of an anomaly, this global flag has a bit set that | ||
36 | * will permantly disable all ring buffers. | ||
37 | */ | ||
38 | |||
39 | /* | ||
40 | * Global flag to disable all recording to ring buffers | ||
41 | * This has two bits: ON, DISABLED | ||
42 | * | ||
43 | * ON DISABLED | ||
44 | * ---- ---------- | ||
45 | * 0 0 : ring buffers are off | ||
46 | * 1 0 : ring buffers are on | ||
47 | * X 1 : ring buffers are permanently disabled | ||
48 | */ | ||
49 | |||
50 | enum { | ||
51 | RB_BUFFERS_ON_BIT = 0, | ||
52 | RB_BUFFERS_DISABLED_BIT = 1, | ||
53 | }; | ||
54 | |||
55 | enum { | ||
56 | RB_BUFFERS_ON = 1 << RB_BUFFERS_ON_BIT, | ||
57 | RB_BUFFERS_DISABLED = 1 << RB_BUFFERS_DISABLED_BIT, | ||
58 | }; | ||
59 | |||
60 | static long ring_buffer_flags __read_mostly = RB_BUFFERS_ON; | ||
23 | 61 | ||
24 | /** | 62 | /** |
25 | * tracing_on - enable all tracing buffers | 63 | * tracing_on - enable all tracing buffers |
@@ -29,7 +67,7 @@ static int ring_buffers_off __read_mostly; | |||
29 | */ | 67 | */ |
30 | void tracing_on(void) | 68 | void tracing_on(void) |
31 | { | 69 | { |
32 | ring_buffers_off = 0; | 70 | set_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags); |
33 | } | 71 | } |
34 | 72 | ||
35 | /** | 73 | /** |
@@ -42,7 +80,18 @@ void tracing_on(void) | |||
42 | */ | 80 | */ |
43 | void tracing_off(void) | 81 | void tracing_off(void) |
44 | { | 82 | { |
45 | ring_buffers_off = 1; | 83 | clear_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags); |
84 | } | ||
85 | |||
86 | /** | ||
87 | * tracing_off_permanent - permanently disable ring buffers | ||
88 | * | ||
89 | * This function, once called, will disable all ring buffers | ||
90 | * permanenty. | ||
91 | */ | ||
92 | void tracing_off_permanent(void) | ||
93 | { | ||
94 | set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags); | ||
46 | } | 95 | } |
47 | 96 | ||
48 | #include "trace.h" | 97 | #include "trace.h" |
@@ -1185,7 +1234,7 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer, | |||
1185 | struct ring_buffer_event *event; | 1234 | struct ring_buffer_event *event; |
1186 | int cpu, resched; | 1235 | int cpu, resched; |
1187 | 1236 | ||
1188 | if (ring_buffers_off) | 1237 | if (ring_buffer_flags != RB_BUFFERS_ON) |
1189 | return NULL; | 1238 | return NULL; |
1190 | 1239 | ||
1191 | if (atomic_read(&buffer->record_disabled)) | 1240 | if (atomic_read(&buffer->record_disabled)) |
@@ -1297,7 +1346,7 @@ int ring_buffer_write(struct ring_buffer *buffer, | |||
1297 | int ret = -EBUSY; | 1346 | int ret = -EBUSY; |
1298 | int cpu, resched; | 1347 | int cpu, resched; |
1299 | 1348 | ||
1300 | if (ring_buffers_off) | 1349 | if (ring_buffer_flags != RB_BUFFERS_ON) |
1301 | return -EBUSY; | 1350 | return -EBUSY; |
1302 | 1351 | ||
1303 | if (atomic_read(&buffer->record_disabled)) | 1352 | if (atomic_read(&buffer->record_disabled)) |
@@ -2178,12 +2227,14 @@ static ssize_t | |||
2178 | rb_simple_read(struct file *filp, char __user *ubuf, | 2227 | rb_simple_read(struct file *filp, char __user *ubuf, |
2179 | size_t cnt, loff_t *ppos) | 2228 | size_t cnt, loff_t *ppos) |
2180 | { | 2229 | { |
2181 | int *p = filp->private_data; | 2230 | long *p = filp->private_data; |
2182 | char buf[64]; | 2231 | char buf[64]; |
2183 | int r; | 2232 | int r; |
2184 | 2233 | ||
2185 | /* !ring_buffers_off == tracing_on */ | 2234 | if (test_bit(RB_BUFFERS_DISABLED_BIT, p)) |
2186 | r = sprintf(buf, "%d\n", !*p); | 2235 | r = sprintf(buf, "permanently disabled\n"); |
2236 | else | ||
2237 | r = sprintf(buf, "%d\n", test_bit(RB_BUFFERS_ON_BIT, p)); | ||
2187 | 2238 | ||
2188 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 2239 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
2189 | } | 2240 | } |
@@ -2192,7 +2243,7 @@ static ssize_t | |||
2192 | rb_simple_write(struct file *filp, const char __user *ubuf, | 2243 | rb_simple_write(struct file *filp, const char __user *ubuf, |
2193 | size_t cnt, loff_t *ppos) | 2244 | size_t cnt, loff_t *ppos) |
2194 | { | 2245 | { |
2195 | int *p = filp->private_data; | 2246 | long *p = filp->private_data; |
2196 | char buf[64]; | 2247 | char buf[64]; |
2197 | long val; | 2248 | long val; |
2198 | int ret; | 2249 | int ret; |
@@ -2209,8 +2260,10 @@ rb_simple_write(struct file *filp, const char __user *ubuf, | |||
2209 | if (ret < 0) | 2260 | if (ret < 0) |
2210 | return ret; | 2261 | return ret; |
2211 | 2262 | ||
2212 | /* !ring_buffers_off == tracing_on */ | 2263 | if (val) |
2213 | *p = !val; | 2264 | set_bit(RB_BUFFERS_ON_BIT, p); |
2265 | else | ||
2266 | clear_bit(RB_BUFFERS_ON_BIT, p); | ||
2214 | 2267 | ||
2215 | (*ppos)++; | 2268 | (*ppos)++; |
2216 | 2269 | ||
@@ -2232,7 +2285,7 @@ static __init int rb_init_debugfs(void) | |||
2232 | d_tracer = tracing_init_dentry(); | 2285 | d_tracer = tracing_init_dentry(); |
2233 | 2286 | ||
2234 | entry = debugfs_create_file("tracing_on", 0644, d_tracer, | 2287 | entry = debugfs_create_file("tracing_on", 0644, d_tracer, |
2235 | &ring_buffers_off, &rb_simple_fops); | 2288 | &ring_buffer_flags, &rb_simple_fops); |
2236 | if (!entry) | 2289 | if (!entry) |
2237 | pr_warning("Could not create debugfs 'tracing_on' entry\n"); | 2290 | pr_warning("Could not create debugfs 'tracing_on' entry\n"); |
2238 | 2291 | ||