Commit d6d033c7 authored by Tom Zanussi's avatar Tom Zanussi Committed by Greg Kroah-Hartman

relay: fix "full buffer with exactly full last subbuffer" accounting problem

commit 32194450 upstream

In relay's current read implementation, if the buffer is completely full
but hasn't triggered the buffer-full condition (i.e. the last write
didn't cross the subbuffer boundary) and the last subbuffer is exactly
full, the subbuffer accounting code erroneously finds nothing available.
This patch fixes the problem.
Signed-off-by: default avatarTom Zanussi <tzanussi@gmail.com>
Cc: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Jens Axboe <jens.axboe@oracle.com>
Cc: Mathieu Desnoyers <compudj@krystal.dyndns.org>
Cc: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 1d1150e2
...@@ -832,6 +832,10 @@ static void relay_file_read_consume(struct rchan_buf *buf, ...@@ -832,6 +832,10 @@ static void relay_file_read_consume(struct rchan_buf *buf,
size_t n_subbufs = buf->chan->n_subbufs; size_t n_subbufs = buf->chan->n_subbufs;
size_t read_subbuf; size_t read_subbuf;
if (buf->subbufs_produced == buf->subbufs_consumed &&
buf->offset == buf->bytes_consumed)
return;
if (buf->bytes_consumed + bytes_consumed > subbuf_size) { if (buf->bytes_consumed + bytes_consumed > subbuf_size) {
relay_subbufs_consumed(buf->chan, buf->cpu, 1); relay_subbufs_consumed(buf->chan, buf->cpu, 1);
buf->bytes_consumed = 0; buf->bytes_consumed = 0;
...@@ -863,6 +867,8 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos) ...@@ -863,6 +867,8 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
relay_file_read_consume(buf, read_pos, 0); relay_file_read_consume(buf, read_pos, 0);
consumed = buf->subbufs_consumed;
if (unlikely(buf->offset > subbuf_size)) { if (unlikely(buf->offset > subbuf_size)) {
if (produced == consumed) if (produced == consumed)
return 0; return 0;
...@@ -881,8 +887,12 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos) ...@@ -881,8 +887,12 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
if (consumed > produced) if (consumed > produced)
produced += n_subbufs * subbuf_size; produced += n_subbufs * subbuf_size;
if (consumed == produced) if (consumed == produced) {
if (buf->offset == subbuf_size &&
buf->subbufs_produced > buf->subbufs_consumed)
return 1;
return 0; return 0;
}
return 1; return 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment