]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
relay: fix "full buffer with exactly full last subbuffer" accounting problem
authorTom Zanussi <tzanussi@gmail.com>
Wed, 6 Aug 2008 00:05:03 +0000 (00:05 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 20 Aug 2008 18:15:23 +0000 (11:15 -0700)
commit 32194450330be327f3b25bf6b66298bd122599e9 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: Tom 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
kernel/relay.c

index d6204a4858183c754d5d401ad230c11f60a546c1..ee2e614a34485ea95fc6c06c6fb5c7d7c5458b4a 100644 (file)
@@ -803,6 +803,10 @@ static void relay_file_read_consume(struct rchan_buf *buf,
        size_t n_subbufs = buf->chan->n_subbufs;
        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) {
                relay_subbufs_consumed(buf->chan, buf->cpu, 1);
                buf->bytes_consumed = 0;
@@ -834,6 +838,8 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
 
        relay_file_read_consume(buf, read_pos, 0);
 
+       consumed = buf->subbufs_consumed;
+
        if (unlikely(buf->offset > subbuf_size)) {
                if (produced == consumed)
                        return 0;
@@ -852,8 +858,12 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos)
        if (consumed > produced)
                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 1;
 }