On Mon, Mar 28, 2016 at 06:41:29AM +0000, Wang Nan wrote:
Add new ioctl() to pause/resume ring-buffer output.I made the below changes.
In some situations we want to read from ring buffer only when we
ensure nothing can write to the ring buffer during reading. Without
this patch we have to turn off all events attached to this ring buffer
to achieve this.
This patch is for supporting overwrite ring buffer. Following
commits will introduce new methods support reading from overwrite ring
buffer. Before reading, caller must ensure the ring buffer is frozen, or
the reading is unreliable.
Signed-off-by: Wang Nan <wangnan0@xxxxxxxxxx>
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4346,7 +4346,7 @@ static long _perf_ioctl(struct perf_even
rcu_read_lock();
rb = rcu_dereference(event->rb);
- if (!event->rb) {
+ if (!event->rb || !event->nr_pages) {
rcu_read_unlock();
return -EINVAL;
}
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -66,9 +66,7 @@ static inline void rb_free_rcu(struct rc
rb_free(rb);
}
-static inline void
-rb_toggle_paused(struct ring_buffer *rb,
- bool pause)
+static inline void rb_toggle_paused(struct ring_buffer *rb, bool pause)
{
if (!pause && rb->nr_pages)
rb->paused = 0;
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -248,7 +248,12 @@ ring_buffer_init(struct ring_buffer *rb,
spin_lock_init(&rb->event_lock);
init_irq_work(&rb->irq_work, rb_irq_work);
- rb->paused = rb->nr_pages ? 0 : 1;
+ /*
+ * perf_output_begin() only checks rb->paused, therefore
+ * rb->paused must be true if we have no pages for output.
+ */
+ if (!rb->nr_pages)
+ rb->paused = 1;
}
static void ring_buffer_put_async(struct ring_buffer *rb)