[RFC PATCH 6/8] relay - Replace relay_reserve/relay_write with non-padded versions.

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Tom Zanussi
Date: Wednesday, September 24, 2008 - 11:07 pm

Replace relay_reserve/relay_write with non-padded versions.

The old versions of relay_reserve/relay_write would write/reserve an
event only if the whole thing could fit in the remaining space of the
current sub-buffer; if it couldn't it would add padding to the current
sub-buffer and reserve in the next.  The new versions don't add
padding but use up all the space in a sub-buffer and write the
remainder in the next sub-buffer.  They won't however write a partial
event - if there's not enough space for the event in the current
sub-buffer and the next sub-buffer isn't free, the whole reserve/write
will fail.
---
 include/linux/relay.h |   41 +++++++++++++++++++----------
 kernel/relay.c        |   69 +++++++++++++++++++++++++++----------------------
 2 files changed, 65 insertions(+), 45 deletions(-)

diff --git a/include/linux/relay.h b/include/linux/relay.h
index 13163b0..c42b2d3 100644
--- a/include/linux/relay.h
+++ b/include/linux/relay.h
@@ -207,9 +207,9 @@ extern void relay_subbufs_consumed(struct rchan *chan,
 extern void relay_reset(struct rchan *chan);
 extern int relay_buf_full(struct rchan_buf *buf);
 
-extern size_t switch_subbuf_default_callback(struct rchan_buf *buf,
-					     size_t length,
-					     void **reserved);
+extern size_t relay_switch_subbuf_default_callback(struct rchan_buf *buf,
+						   size_t length,
+						   void **reserved);
 
 /**
  *	relay_event_toobig - is event too big to fit in a sub-buffer?
@@ -270,17 +270,23 @@ static inline void relay_write(struct rchan *chan,
 			       const void *data,
 			       size_t length)
 {
-	unsigned long flags;
+	size_t remainder = length;
 	struct rchan_buf *buf;
+	unsigned long flags;
 	void *reserved;
 
 	local_irq_save(flags);
 	buf = chan->buf[smp_processor_id()];
 	reserved = buf->data + buf->offset;
-	if (unlikely(buf->offset + length > chan->subbuf_size))
-		length = chan->cb->switch_subbuf(buf, length, &reserved);
+	if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
+		remainder = chan->cb->switch_subbuf(buf, length, &reserved);
+		if (unlikely(!reserved)) {
+			local_irq_restore(flags);
+			return;
+		}
+	}
 	memcpy(reserved, data, length);
-	buf->offset += length;
+	buf->offset += remainder;
 	local_irq_restore(flags);
 }
 
@@ -300,15 +306,22 @@ static inline void __relay_write(struct rchan *chan,
 				 const void *data,
 				 size_t length)
 {
+	size_t remainder = length;
 	struct rchan_buf *buf;
+	unsigned long flags;
 	void *reserved;
 
 	buf = chan->buf[get_cpu()];
 	reserved = buf->data + buf->offset;
-	if (unlikely(buf->offset + length > buf->chan->subbuf_size))
-		length = chan->cb->switch_subbuf(buf, length, &reserved);
+	if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
+		remainder = chan->cb->switch_subbuf(buf, length, &reserved);
+		if (unlikely(!reserved)) {
+			local_irq_restore(flags);
+			return;
+		}
+	}
 	memcpy(reserved, data, length);
-	buf->offset += length;
+	buf->offset += remainder;
 	put_cpu();
 }
 
@@ -323,15 +336,15 @@ static inline void __relay_write(struct rchan *chan,
  *	Does not protect the buffer at all - caller must provide
  *	appropriate synchronization.
  */
-static inline void *relay_reserve(struct rchan *chan, size_t length)
+static inline void *relay_reserve(struct rchan *chan,
+				  size_t length)
 {
-	void *reserved;
 	struct rchan_buf *buf = chan->buf[smp_processor_id()];
+	void *reserved = buf->data + buf->offset;
 
-	reserved = buf->data + buf->offset;
 	if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
 		length = chan->cb->switch_subbuf(buf, length, &reserved);
-		if (!length)
+		if (unlikely(!reserved))
 			return NULL;
 	}
 	buf->offset += length;
diff --git a/kernel/relay.c b/kernel/relay.c
index 9a08fec..15e4de2 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -350,7 +350,7 @@ static struct rchan_callbacks default_channel_callbacks = {
 	.create_buf_file = create_buf_file_default_callback,
 	.remove_buf_file = remove_buf_file_default_callback,
 	.wakeup_readers = wakeup_readers_default_callback,
-	.switch_subbuf = switch_subbuf_default_callback,
+	.switch_subbuf = relay_switch_subbuf_default_callback,
 };
 
 /**
@@ -530,7 +530,7 @@ static void setup_callbacks(struct rchan *chan,
 	if (!cb->wakeup_readers)
 		cb->wakeup_readers = wakeup_readers_default_callback;
 	if (!cb->switch_subbuf)
-		cb->switch_subbuf = switch_subbuf_default_callback;
+		cb->switch_subbuf = relay_switch_subbuf_default_callback;
 	chan->cb = cb;
 }
 
@@ -736,8 +736,20 @@ int relay_late_setup_files(struct rchan *chan,
 	return err;
 }
 
+static inline int next_subbuf_free(struct rchan_buf *buf)
+{
+	size_t full_subbufs;
+
+	if (buf->chan->flags & RCHAN_MODE_OVERWRITE)
+		return 1;
+
+	full_subbufs = buf->subbufs_produced - buf->subbufs_consumed;
+
+	return (full_subbufs < buf->chan->n_subbufs - 1);
+}
+
 /**
- *	switch_subbuf_default_callback - switch to a new sub-buffer
+ *	relay_switch_subbuf_default_callback - switch to a new sub-buffer
  *	@buf: channel buffer
  *	@length: size of current event
  *	@reserved: a pointer to the space reserved
@@ -747,50 +759,45 @@ int relay_late_setup_files(struct rchan *chan,
  *	Performs sub-buffer-switch tasks such as invoking callbacks,
  *	updating padding counts, waking up readers, etc.
  */
-size_t switch_subbuf_default_callback(struct rchan_buf *buf,
-				      size_t length,
-				      void **reserved)
+size_t relay_switch_subbuf_default_callback(struct rchan_buf *buf,
+					    size_t length,
+					    void **reserved)
 {
-	void *old, *new;
-	size_t old_subbuf, new_subbuf;
+	size_t remainder, new_subbuf;
+	void *new_data;
 
 	if (unlikely(relay_event_toobig(buf, length)))
 		goto toobig;
 
-	if (buf->offset != buf->chan->subbuf_size + 1) {
-		buf->prev_padding = buf->chan->subbuf_size - buf->offset;
-		old_subbuf = buf->subbufs_produced % buf->chan->n_subbufs;
-		buf->padding[old_subbuf] = buf->prev_padding;
-		relay_inc_produced(buf);
-		relay_update_filesize(buf, buf->chan->subbuf_size -
-				      buf->padding[old_subbuf]);
-		buf->chan->cb->wakeup_readers(buf);
+	/* don't write anything unless we can write it all. */
+	if (!next_subbuf_free(buf)) {
+		*reserved = NULL;
+		return 0;
 	}
 
-	old = buf->data;
+	if (reserved)
+		*reserved = buf->data + buf->offset;
+
+	remainder = length - (buf->chan->subbuf_size - buf->offset);
+	relay_inc_produced(buf);
+	relay_update_filesize(buf, buf->chan->subbuf_size + remainder);
+	buf->chan->cb->wakeup_readers(buf);
+
 	new_subbuf = buf->subbufs_produced % buf->chan->n_subbufs;
-	new = buf->start + new_subbuf * buf->chan->subbuf_size;
-	buf->offset = 0;
-	if (!buf->chan->cb->subbuf_start(buf, new, old, buf->prev_padding)) {
-		buf->offset = buf->chan->subbuf_size + 1;
-		return 0;
-	}
-	buf->data = new;
-	buf->padding[new_subbuf] = 0;
+	new_data = buf->start + new_subbuf * buf->chan->subbuf_size;
+
+	buf->data = new_data;
+	buf->offset = 0; /* remainder will be added by caller */
 
 	if (unlikely(relay_event_toobig(buf, length + buf->offset)))
 		goto toobig;
 
-	if (reserved)
-		*reserved = buf->data;
-
-	return length;
-
+	return remainder;
 toobig:
 	buf->chan->last_toobig = length;
 	return 0;
 }
-EXPORT_SYMBOL_GPL(switch_subbuf_default_callback);
+EXPORT_SYMBOL_GPL(relay_switch_subbuf_default_callback);
 
 /**
  *	relay_subbufs_consumed - update the buffer's sub-buffers-consumed count
-- 
1.5.3.5



--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Unified tracing buffer, Martin Bligh, (Fri Sep 19, 2:33 pm)
Re: Unified tracing buffer, Randy Dunlap, (Fri Sep 19, 2:42 pm)
Re: Unified tracing buffer, Martin Bligh, (Fri Sep 19, 2:57 pm)
Re: Unified tracing buffer, Martin Bligh, (Fri Sep 19, 3:09 pm)
Re: Unified tracing buffer, Martin Bligh, (Fri Sep 19, 3:19 pm)
Re: Unified tracing buffer, Olaf Dabrunz, (Fri Sep 19, 3:28 pm)
Re: Unified tracing buffer, Olaf Dabrunz, (Fri Sep 19, 3:41 pm)
Re: Unified tracing buffer, Frank Ch. Eigler, (Fri Sep 19, 4:18 pm)
Re: Unified tracing buffer, Peter Zijlstra, (Fri Sep 19, 5:07 pm)
Re: Unified tracing buffer, Marcel Holtmann, (Fri Sep 19, 5:26 pm)
Re: Unified tracing buffer, Olaf Dabrunz, (Sat Sep 20, 1:10 am)
Re: Unified tracing buffer, Steven Rostedt, (Sat Sep 20, 1:26 am)
Re: Unified tracing buffer, Steven Rostedt, (Sat Sep 20, 1:29 am)
Re: Unified tracing buffer, Steven Rostedt, (Sat Sep 20, 1:50 am)
Re: Unified tracing buffer, Steven Rostedt, (Sat Sep 20, 2:03 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Sat Sep 20, 4:40 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Sat Sep 20, 4:44 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Sat Sep 20, 6:37 am)
Re: Unified tracing buffer, Steven Rostedt, (Sat Sep 20, 6:51 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Sat Sep 20, 6:55 am)
Re: Unified tracing buffer, Arjan van de Ven, (Sat Sep 20, 7:12 am)
Re: Unified tracing buffer, Steven Rostedt, (Sat Sep 20, 7:54 am)
Re: Unified tracing buffer, KOSAKI Motohiro, (Sun Sep 21, 8:09 pm)
Re: Unified tracing buffer, Peter Zijlstra, (Mon Sep 22, 2:57 am)
Re: Unified tracing buffer, K.Prasad, (Mon Sep 22, 6:57 am)
Re: Unified tracing buffer, K.Prasad, (Mon Sep 22, 7:07 am)
Re: Unified tracing buffer, Peter Zijlstra, (Mon Sep 22, 7:45 am)
Re: Unified tracing buffer, Martin Bligh, (Mon Sep 22, 9:29 am)
Re: Unified tracing buffer, Peter Zijlstra, (Mon Sep 22, 9:36 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 11:45 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 11:52 am)
Re: Unified tracing buffer, Masami Hiramatsu, (Mon Sep 22, 12:45 pm)
Re: Unified tracing buffer, Martin Bligh, (Mon Sep 22, 1:13 pm)
Re: Unified tracing buffer, Masami Hiramatsu, (Mon Sep 22, 1:50 pm)
Re: Unified tracing buffer, Steven Rostedt, (Mon Sep 22, 2:39 pm)
Re: Unified tracing buffer, Masami Hiramatsu, (Mon Sep 22, 3:25 pm)
Re: Unified tracing buffer, Darren Hart, (Mon Sep 22, 4:11 pm)
Re: Unified tracing buffer, Martin Bligh, (Mon Sep 22, 4:16 pm)
Re: Unified tracing buffer, Masami Hiramatsu, (Mon Sep 22, 5:04 pm)
Re: Unified tracing buffer, Masami Hiramatsu, (Mon Sep 22, 5:05 pm)
Re: Unified tracing buffer, Martin Bligh, (Mon Sep 22, 5:12 pm)
Re: Unified tracing buffer, Linus Torvalds, (Mon Sep 22, 5:39 pm)
Re: Unified tracing buffer, Roland Dreier, (Mon Sep 22, 6:26 pm)
Re: Unified tracing buffer, Steven Rostedt, (Mon Sep 22, 6:39 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 7:02 pm)
Re: Unified tracing buffer, Darren Hart, (Mon Sep 22, 7:26 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 7:30 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 7:31 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 7:36 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 7:49 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 8:05 pm)
Re: Unified tracing buffer, Masami Hiramatsu, (Mon Sep 22, 8:06 pm)
Re: Unified tracing buffer, Linus Torvalds, (Mon Sep 22, 8:26 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 8:27 pm)
Re: Unified tracing buffer, Andi Kleen, (Mon Sep 22, 8:33 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Mon Sep 22, 8:36 pm)
Re: Unified tracing buffer, Steven Rostedt, (Mon Sep 22, 8:43 pm)
Re: Unified tracing buffer, Martin Bligh, (Mon Sep 22, 8:47 pm)
Re: Unified tracing buffer, Linus Torvalds, (Mon Sep 22, 9:05 pm)
Re: Unified tracing buffer, Masami Hiramatsu, (Mon Sep 22, 9:10 pm)
Re: Unified tracing buffer, Martin Bligh, (Mon Sep 22, 9:17 pm)
Re: Unified tracing buffer, Linus Torvalds, (Mon Sep 22, 9:19 pm)
Re: Unified tracing buffer, Andi Kleen, (Mon Sep 22, 10:04 pm)
Re: Unified tracing buffer, Tom Zanussi, (Mon Sep 22, 10:25 pm)
[PATCH 1/3] relay - clean up subbuf switch, Tom Zanussi, (Mon Sep 22, 10:27 pm)
[PATCH 2/3] relay - make subbuf switch replaceable, Tom Zanussi, (Mon Sep 22, 10:27 pm)
[PATCH 3/3] relay - add channel flags, Tom Zanussi, (Mon Sep 22, 10:27 pm)
Re: Unified tracing buffer, Peter Zijlstra, (Tue Sep 23, 2:31 am)
Re: Unified tracing buffer, Steven Rostedt, (Tue Sep 23, 3:53 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Tue Sep 23, 6:50 am)
Re: Unified tracing buffer, Martin Bligh, (Tue Sep 23, 7:00 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Tue Sep 23, 7:12 am)
Re: Unified tracing buffer, KOSAKI Motohiro, (Tue Sep 23, 7:36 am)
Re: Unified tracing buffer, Masami Hiramatsu, (Tue Sep 23, 7:49 am)
Re: Unified tracing buffer, Frank Ch. Eigler, (Tue Sep 23, 8:02 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Tue Sep 23, 8:04 am)
Re: Unified tracing buffer, Masami Hiramatsu, (Tue Sep 23, 8:21 am)
Re: Unified tracing buffer, Masami Hiramatsu, (Tue Sep 23, 8:23 am)
Re: Unified tracing buffer, Masami Hiramatsu, (Tue Sep 23, 8:30 am)
Re: Unified tracing buffer, Linus Torvalds, (Tue Sep 23, 8:46 am)
Re: Unified tracing buffer, Linus Torvalds, (Tue Sep 23, 9:01 am)
Re: Unified tracing buffer, Masami Hiramatsu, (Tue Sep 23, 10:04 am)
Re: Unified tracing buffer, Thomas Gleixner, (Tue Sep 23, 10:30 am)
Re: Unified tracing buffer, K.Prasad, (Tue Sep 23, 10:55 am)
Re: Unified tracing buffer, KOSAKI Motohiro, (Tue Sep 23, 10:59 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Tue Sep 23, 11:13 am)
Re: Unified tracing buffer, Martin Bligh, (Tue Sep 23, 11:27 am)
Re: Unified tracing buffer, Martin Bligh, (Tue Sep 23, 11:28 am)
Re: Unified tracing buffer, Christoph Lameter, (Tue Sep 23, 11:33 am)
Re: Unified tracing buffer, Linus Torvalds, (Tue Sep 23, 11:56 am)
Re: Unified tracing buffer, Masami Hiramatsu, (Tue Sep 23, 11:59 am)
Re: Unified tracing buffer, Thomas Gleixner, (Tue Sep 23, 12:36 pm)
Re: Unified tracing buffer, Martin Bligh, (Tue Sep 23, 12:38 pm)
Re: Unified tracing buffer, Thomas Gleixner, (Tue Sep 23, 12:41 pm)
Re: Unified tracing buffer, Martin Bligh, (Tue Sep 23, 12:50 pm)
Re: Unified tracing buffer, Thomas Gleixner, (Tue Sep 23, 1:03 pm)
Re: Unified tracing buffer, Masami Hiramatsu, (Tue Sep 23, 1:03 pm)
Re: Unified tracing buffer, Thomas Gleixner, (Tue Sep 23, 1:08 pm)
Re: [PATCH 1/3] relay - clean up subbuf switch, Andrew Morton, (Tue Sep 23, 1:15 pm)
Re: [PATCH 2/3] relay - make subbuf switch replaceable, Andrew Morton, (Tue Sep 23, 1:17 pm)
Re: [PATCH 3/3] relay - add channel flags, Andrew Morton, (Tue Sep 23, 1:20 pm)
Re: Unified tracing buffer, Martin Bligh, (Tue Sep 23, 2:02 pm)
Re: Unified tracing buffer, Tom Zanussi, (Tue Sep 23, 8:50 pm)
Re: [PATCH 3/3] relay - add channel flags, Tom Zanussi, (Tue Sep 23, 8:57 pm)
Re: Unified tracing buffer, K.Prasad, (Tue Sep 23, 10:42 pm)
[RFC PATCH 0/8] current relay cleanup patchset, Tom Zanussi, (Wed Sep 24, 11:07 pm)
[RFC PATCH 6/8] relay - Replace relay_reserve/relay_write ..., Tom Zanussi, (Wed Sep 24, 11:07 pm)
Re: Unified tracing buffer, Jason Baron, (Thu Oct 2, 8:28 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Fri Oct 3, 9:11 am)
Re: Unified tracing buffer, Jason Baron, (Fri Oct 3, 11:37 am)
Re: Unified tracing buffer, Mathieu Desnoyers, (Fri Oct 3, 12:10 pm)
Re: Unified tracing buffer, Jason Baron, (Fri Oct 3, 12:25 pm)
Re: Unified tracing buffer, Mathieu Desnoyers, (Fri Oct 3, 12:56 pm)
Re: Unified tracing buffer, Jason Baron, (Fri Oct 3, 1:25 pm)
Re: Unified tracing buffer, Frank Ch. Eigler, (Fri Oct 3, 2:52 pm)