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(-)
diff --git a/include/linux/relay.h b/include/linux/relay.h
index 978fdea..21eba2a 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);
/**
@@ -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, ...