BUG/MINOR: ring: fix lost reader wakeup on a message being written

Since commit cb482f92c4 ("MINOR: ring: make sure ring_dispatch waits when
facing a changing message"), a reader's pass stops on a message whose
writer is still copying it. The tail already covers that message, so the
check made after registering in ring->waiters (did the tail move since the
pass started ?) cannot see it complete. If the writer completes and wakes
the waiters between the end of the pass and the registration, the wakeup
is lost and the reader sleeps with a complete message in the ring until
another one is written.

For the log forwarder ("log tcp@", log backends, ring sections with
servers) and "show events -w", this means that lines stay unsent until the
next message, possibly for a long time on a quiet ring, and are lost if the
process dies meanwhile. It was seen in 3 bursts out of 30000 on an
unmodified build, and can be reproduced by delaying a writer and a reader.

Let's instead check once registered whether a complete message is
available at the reader's offset, using the new ring_msg_ready(). A barrier
orders the registration before this check, which is free on x86. The tail
comparison being replaced, last_ofs_ptr is now unused and is removed from
ring_dispatch_messages().

This must be backported to 3.0 and above.

Attachment: 0001-BUG-MINOR-ring-fix-lost-reader-wakeup-on-a-message-b.patch
Description: Binary data

Reply via email to