Skip to contentSkip to conversation

tracing: poll-able ring_buffer consumer

PATCH In review Lai Jiangshan 2 participants 2 messages Aug 27, 2009 – Sep 9, 2009

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 3/3 tracing: poll-able ring_buffer consumer

makes consumer side(per_cpu/cpu#/trace_pipe_raw) poll-able

---

include/linux/ring_buffer.h +3 -0
index b81ceed..6fd2664 100644
@@ -4,6 +4,7 @@
 #include <linux/kmemcheck.h>
 #include <linux/mm.h>
 #include <linux/seq_file.h>
+#include <linux/poll.h>
 
 struct ring_buffer;
 struct ring_buffer_iter;
@@ -188,6 +189,8 @@ int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page,
 void ring_buffer_notify(struct ring_buffer *buffer);
 signed long ring_buffer_wait_page(struct ring_buffer *buffer, int cpu,
 		signed long timeout);
+unsigned int ring_buffer_poll(struct ring_buffer *buffer, int cpu,
+		struct file *filp, poll_table *poll_table);
 
 struct trace_seq;
 
kernel/trace/ring_buffer.c +16 -0
index db82b38..c7c23da 100644
@@ -3389,6 +3389,22 @@ ring_buffer_wait_page(struct ring_buffer *buffer, int cpu, signed long timeout)
 			rb_page_available(cpu_buffer), timeout);
 }
 
+unsigned int ring_buffer_poll(struct ring_buffer *buffer, int cpu,
+		struct file *filp, poll_table *poll_table)
+{
+	struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
+
+	if (rb_page_available(cpu_buffer))
+		return POLLIN | POLLRDNORM;
+
+	poll_wait(filp, &cpu_buffer->sleepers, poll_table);
+
+	if (rb_page_available(cpu_buffer))
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
 /**
  * ring_buffer_size - return the size of the ring buffer (in bytes)
  * @buffer: The ring buffer.
kernel/trace/trace.c +9 -0
index ee435ed..c2aa14c 100644
@@ -3294,6 +3294,14 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
+static
+unsigned int tracing_buffers_poll(struct file *filp, poll_table *poll_table)
+{
+	struct ftrace_buffer_info *info = filp->private_data;
+
+	return ring_buffer_poll(info->tr->buffer, info->cpu, filp, poll_table);
+}
+
 struct buffer_ref {
 	struct ring_buffer	*buffer;
 	void			*page;
@@ -3459,6 +3467,7 @@ static const struct file_operations tracing_buffers_fops = {
 	.open		= tracing_buffers_open,
 	.read		= tracing_buffers_read,
 	.release	= tracing_buffers_release,
+	.poll		= tracing_buffers_poll,
 	.splice_read	= tracing_buffers_splice_read,
 	.llseek		= no_llseek,
 };
maintainer
#1 lore raw
Quoted 30 lines · Lai Jiangshan

makes consumer side(per_cpu/cpu#/trace_pipe_raw) poll-able

---

include/linux/ring_buffer.h +3 -0
index b81ceed..6fd2664 100644
@@ -4,6 +4,7 @@
 #include <linux/kmemcheck.h>
 #include <linux/mm.h>
 #include <linux/seq_file.h>
+#include <linux/poll.h>
 
 struct ring_buffer;
 struct ring_buffer_iter;
@@ -188,6 +189,8 @@ int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page,
 void ring_buffer_notify(struct ring_buffer *buffer);
 signed long ring_buffer_wait_page(struct ring_buffer *buffer, int cpu,
 		signed long timeout);
+unsigned int ring_buffer_poll(struct ring_buffer *buffer, int cpu,
+		struct file *filp, poll_table *poll_table);
 
 struct trace_seq;
 
kernel/trace/ring_buffer.c +0 -0
index db82b38..c7c23da 100644

kernel/trace/ring_buffer.c ring_buffer_wait_page(struct ring_buffer *buffer, int cpu, signed long timeout) · line 3391

Quoted 3 lines
kernel/trace/ring_buffer.c +0 -0
@@ -3389,6 +3389,22 @@ ring_buffer_wait_page(struct ring_buffer *buffer, int cpu, signed long timeout)
 			rb_page_available(cpu_buffer), timeout);
 }
 

/**
* ring_buffer_poll --- COMMENT ME ;-)
...

Quoted 39 lines
kernel/trace/ring_buffer.c +16 -0
+unsigned int ring_buffer_poll(struct ring_buffer *buffer, int cpu,
+		struct file *filp, poll_table *poll_table)
+{
+	struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
+
+	if (rb_page_available(cpu_buffer))
+		return POLLIN | POLLRDNORM;
+
+	poll_wait(filp, &cpu_buffer->sleepers, poll_table);
+
+	if (rb_page_available(cpu_buffer))
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
 /**
  * ring_buffer_size - return the size of the ring buffer (in bytes)
  * @buffer: The ring buffer.
kernel/trace/trace.c +8 -0
index ee435ed..c2aa14c 100644
@@ -3294,6 +3294,14 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
 	return 0;
 }
 
+static
+unsigned int tracing_buffers_poll(struct file *filp, poll_table *poll_table)
+{
+	struct ftrace_buffer_info *info = filp->private_data;
+
+	return ring_buffer_poll(info->tr->buffer, info->cpu, filp, poll_table);
+}
+
 struct buffer_ref {
 	struct ring_buffer	*buffer;
 	void			*page;

kernel/trace/trace.c static const struct file_operations tracing_buffers_fops = { · line 3473

Quoted 7 lines
kernel/trace/trace.c +1 -0
@@ -3459,6 +3467,7 @@ static const struct file_operations tracing_buffers_fops = {
 	.open		= tracing_buffers_open,
 	.read		= tracing_buffers_read,
 	.release	= tracing_buffers_release,
+	.poll		= tracing_buffers_poll,
 	.splice_read	= tracing_buffers_splice_read,
 	.llseek		= no_llseek,
 };

I'm fine with this patch. (besides the missing comment)

-- Steve