Commit 32194450330be327f3b25bf6b66298bd122599e9
Committed by
Linus Torvalds
1 parent
60cadec9da
Exists in
master
and in
39 other branches
relay: fix "full buffer with exactly full last subbuffer" accounting problem
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> Cc: <stable@kernel.org> [2.6.25.x, 2.6.26.x] Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 11 additions and 1 deletions Side-by-side Diff
kernel/relay.c
... | ... | @@ -944,6 +944,10 @@ |
944 | 944 | size_t n_subbufs = buf->chan->n_subbufs; |
945 | 945 | size_t read_subbuf; |
946 | 946 | |
947 | + if (buf->subbufs_produced == buf->subbufs_consumed && | |
948 | + buf->offset == buf->bytes_consumed) | |
949 | + return; | |
950 | + | |
947 | 951 | if (buf->bytes_consumed + bytes_consumed > subbuf_size) { |
948 | 952 | relay_subbufs_consumed(buf->chan, buf->cpu, 1); |
949 | 953 | buf->bytes_consumed = 0; |
... | ... | @@ -975,6 +979,8 @@ |
975 | 979 | |
976 | 980 | relay_file_read_consume(buf, read_pos, 0); |
977 | 981 | |
982 | + consumed = buf->subbufs_consumed; | |
983 | + | |
978 | 984 | if (unlikely(buf->offset > subbuf_size)) { |
979 | 985 | if (produced == consumed) |
980 | 986 | return 0; |
981 | 987 | |
... | ... | @@ -993,8 +999,12 @@ |
993 | 999 | if (consumed > produced) |
994 | 1000 | produced += n_subbufs * subbuf_size; |
995 | 1001 | |
996 | - if (consumed == produced) | |
1002 | + if (consumed == produced) { | |
1003 | + if (buf->offset == subbuf_size && | |
1004 | + buf->subbufs_produced > buf->subbufs_consumed) | |
1005 | + return 1; | |
997 | 1006 | return 0; |
1007 | + } | |
998 | 1008 | |
999 | 1009 | return 1; |
1000 | 1010 | } |