diff options
Diffstat (limited to 'kernel/trace/ring_buffer.c')
-rw-r--r-- | kernel/trace/ring_buffer.c | 157 |
1 files changed, 60 insertions, 97 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index f5b7b5c1195b..cf8d11e91efd 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -154,33 +154,10 @@ enum { | |||
154 | 154 | ||
155 | static unsigned long ring_buffer_flags __read_mostly = RB_BUFFERS_ON; | 155 | static unsigned long ring_buffer_flags __read_mostly = RB_BUFFERS_ON; |
156 | 156 | ||
157 | #define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data) | 157 | /* Used for individual buffers (after the counter) */ |
158 | 158 | #define RB_BUFFER_OFF (1 << 20) | |
159 | /** | ||
160 | * tracing_on - enable all tracing buffers | ||
161 | * | ||
162 | * This function enables all tracing buffers that may have been | ||
163 | * disabled with tracing_off. | ||
164 | */ | ||
165 | void tracing_on(void) | ||
166 | { | ||
167 | set_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags); | ||
168 | } | ||
169 | EXPORT_SYMBOL_GPL(tracing_on); | ||
170 | 159 | ||
171 | /** | 160 | #define BUF_PAGE_HDR_SIZE offsetof(struct buffer_data_page, data) |
172 | * tracing_off - turn off all tracing buffers | ||
173 | * | ||
174 | * This function stops all tracing buffers from recording data. | ||
175 | * It does not disable any overhead the tracers themselves may | ||
176 | * be causing. This function simply causes all recording to | ||
177 | * the ring buffers to fail. | ||
178 | */ | ||
179 | void tracing_off(void) | ||
180 | { | ||
181 | clear_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags); | ||
182 | } | ||
183 | EXPORT_SYMBOL_GPL(tracing_off); | ||
184 | 161 | ||
185 | /** | 162 | /** |
186 | * tracing_off_permanent - permanently disable ring buffers | 163 | * tracing_off_permanent - permanently disable ring buffers |
@@ -193,15 +170,6 @@ void tracing_off_permanent(void) | |||
193 | set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags); | 170 | set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags); |
194 | } | 171 | } |
195 | 172 | ||
196 | /** | ||
197 | * tracing_is_on - show state of ring buffers enabled | ||
198 | */ | ||
199 | int tracing_is_on(void) | ||
200 | { | ||
201 | return ring_buffer_flags == RB_BUFFERS_ON; | ||
202 | } | ||
203 | EXPORT_SYMBOL_GPL(tracing_is_on); | ||
204 | |||
205 | #define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) | 173 | #define RB_EVNT_HDR_SIZE (offsetof(struct ring_buffer_event, array)) |
206 | #define RB_ALIGNMENT 4U | 174 | #define RB_ALIGNMENT 4U |
207 | #define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) | 175 | #define RB_MAX_SMALL_DATA (RB_ALIGNMENT * RINGBUF_TYPE_DATA_TYPE_LEN_MAX) |
@@ -2619,6 +2587,63 @@ void ring_buffer_record_enable(struct ring_buffer *buffer) | |||
2619 | EXPORT_SYMBOL_GPL(ring_buffer_record_enable); | 2587 | EXPORT_SYMBOL_GPL(ring_buffer_record_enable); |
2620 | 2588 | ||
2621 | /** | 2589 | /** |
2590 | * ring_buffer_record_off - stop all writes into the buffer | ||
2591 | * @buffer: The ring buffer to stop writes to. | ||
2592 | * | ||
2593 | * This prevents all writes to the buffer. Any attempt to write | ||
2594 | * to the buffer after this will fail and return NULL. | ||
2595 | * | ||
2596 | * This is different than ring_buffer_record_disable() as | ||
2597 | * it works like an on/off switch, where as the disable() verison | ||
2598 | * must be paired with a enable(). | ||
2599 | */ | ||
2600 | void ring_buffer_record_off(struct ring_buffer *buffer) | ||
2601 | { | ||
2602 | unsigned int rd; | ||
2603 | unsigned int new_rd; | ||
2604 | |||
2605 | do { | ||
2606 | rd = atomic_read(&buffer->record_disabled); | ||
2607 | new_rd = rd | RB_BUFFER_OFF; | ||
2608 | } while (atomic_cmpxchg(&buffer->record_disabled, rd, new_rd) != rd); | ||
2609 | } | ||
2610 | EXPORT_SYMBOL_GPL(ring_buffer_record_off); | ||
2611 | |||
2612 | /** | ||
2613 | * ring_buffer_record_on - restart writes into the buffer | ||
2614 | * @buffer: The ring buffer to start writes to. | ||
2615 | * | ||
2616 | * This enables all writes to the buffer that was disabled by | ||
2617 | * ring_buffer_record_off(). | ||
2618 | * | ||
2619 | * This is different than ring_buffer_record_enable() as | ||
2620 | * it works like an on/off switch, where as the enable() verison | ||
2621 | * must be paired with a disable(). | ||
2622 | */ | ||
2623 | void ring_buffer_record_on(struct ring_buffer *buffer) | ||
2624 | { | ||
2625 | unsigned int rd; | ||
2626 | unsigned int new_rd; | ||
2627 | |||
2628 | do { | ||
2629 | rd = atomic_read(&buffer->record_disabled); | ||
2630 | new_rd = rd & ~RB_BUFFER_OFF; | ||
2631 | } while (atomic_cmpxchg(&buffer->record_disabled, rd, new_rd) != rd); | ||
2632 | } | ||
2633 | EXPORT_SYMBOL_GPL(ring_buffer_record_on); | ||
2634 | |||
2635 | /** | ||
2636 | * ring_buffer_record_is_on - return true if the ring buffer can write | ||
2637 | * @buffer: The ring buffer to see if write is enabled | ||
2638 | * | ||
2639 | * Returns true if the ring buffer is in a state that it accepts writes. | ||
2640 | */ | ||
2641 | int ring_buffer_record_is_on(struct ring_buffer *buffer) | ||
2642 | { | ||
2643 | return !atomic_read(&buffer->record_disabled); | ||
2644 | } | ||
2645 | |||
2646 | /** | ||
2622 | * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer | 2647 | * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer |
2623 | * @buffer: The ring buffer to stop writes to. | 2648 | * @buffer: The ring buffer to stop writes to. |
2624 | * @cpu: The CPU buffer to stop | 2649 | * @cpu: The CPU buffer to stop |
@@ -4039,68 +4064,6 @@ int ring_buffer_read_page(struct ring_buffer *buffer, | |||
4039 | } | 4064 | } |
4040 | EXPORT_SYMBOL_GPL(ring_buffer_read_page); | 4065 | EXPORT_SYMBOL_GPL(ring_buffer_read_page); |
4041 | 4066 | ||
4042 | #ifdef CONFIG_TRACING | ||
4043 | static ssize_t | ||
4044 | rb_simple_read(struct file *filp, char __user *ubuf, | ||
4045 | size_t cnt, loff_t *ppos) | ||
4046 | { | ||
4047 | unsigned long *p = filp->private_data; | ||
4048 | char buf[64]; | ||
4049 | int r; | ||
4050 | |||
4051 | if (test_bit(RB_BUFFERS_DISABLED_BIT, p)) | ||
4052 | r = sprintf(buf, "permanently disabled\n"); | ||
4053 | else | ||
4054 | r = sprintf(buf, "%d\n", test_bit(RB_BUFFERS_ON_BIT, p)); | ||
4055 | |||
4056 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | ||
4057 | } | ||
4058 | |||
4059 | static ssize_t | ||
4060 | rb_simple_write(struct file *filp, const char __user *ubuf, | ||
4061 | size_t cnt, loff_t *ppos) | ||
4062 | { | ||
4063 | unsigned long *p = filp->private_data; | ||
4064 | unsigned long val; | ||
4065 | int ret; | ||
4066 | |||
4067 | ret = kstrtoul_from_user(ubuf, cnt, 10, &val); | ||
4068 | if (ret) | ||
4069 | return ret; | ||
4070 | |||
4071 | if (val) | ||
4072 | set_bit(RB_BUFFERS_ON_BIT, p); | ||
4073 | else | ||
4074 | clear_bit(RB_BUFFERS_ON_BIT, p); | ||
4075 | |||
4076 | (*ppos)++; | ||
4077 | |||
4078 | return cnt; | ||
4079 | } | ||
4080 | |||
4081 | static const struct file_operations rb_simple_fops = { | ||
4082 | .open = tracing_open_generic, | ||
4083 | .read = rb_simple_read, | ||
4084 | .write = rb_simple_write, | ||
4085 | .llseek = default_llseek, | ||
4086 | }; | ||
4087 | |||
4088 | |||
4089 | static __init int rb_init_debugfs(void) | ||
4090 | { | ||
4091 | struct dentry *d_tracer; | ||
4092 | |||
4093 | d_tracer = tracing_init_dentry(); | ||
4094 | |||
4095 | trace_create_file("tracing_on", 0644, d_tracer, | ||
4096 | &ring_buffer_flags, &rb_simple_fops); | ||
4097 | |||
4098 | return 0; | ||
4099 | } | ||
4100 | |||
4101 | fs_initcall(rb_init_debugfs); | ||
4102 | #endif | ||
4103 | |||
4104 | #ifdef CONFIG_HOTPLUG_CPU | 4067 | #ifdef CONFIG_HOTPLUG_CPU |
4105 | static int rb_cpu_notify(struct notifier_block *self, | 4068 | static int rb_cpu_notify(struct notifier_block *self, |
4106 | unsigned long action, void *hcpu) | 4069 | unsigned long action, void *hcpu) |