Skip to contentSkip to conversation

relay - Replace relay_reserve/relay_write with non-padded versions.

RFC PATCH In review Tom Zanussi 1 participant 1 message Oct 16, 2008 Relay

lore
Share & tools
lore
#0 lore raw

RFC PATCH 6/21 relay - 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        |   68 ++++++++++++++++++++++++++----------------------
 2 files changed, 64 insertions(+), 45 deletions(-)
include/linux/relay.h +27 -14
index 978fdea..21eba2a 100644
@@ -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);
 
 
 /**
@@ -271,17 +271,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);
 }
 
@@ -301,15 +307,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();
 }
 
@@ -324,15 +337,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;
kernel/relay.c +37 -31

109 lines not on this page · raw message

Signature · 1 line
1.5.3.5