On Tue, Sep 01, 2026 at 05:57:21PM -0400, Noah Meyerhans via dovecot wrote:
On loong64, the test suite fails in test-lib with:
ostream multiplex stream (backpressure): sub-process ended properly .. : FAILED Warning: test: Sub-process forcibly terminated with signal 9 ostream multiplex stream (backpressure) .............................. : FAILED
I'm not quite sure what's going on yet, but the child process in this test is hanging in the write() call in o_stream_file_writev(). I've noticed that if I increase the output buffer size from 4096 to 8192 in test_stream_backpressure_child() then the test passes. See below for the diff. If the buffer was too large and the entire input was consumed, that would still result in a test failure, so I believe this change still exercises the code paths as expected. I'm not entirely sure why this is happening only on loong64, though. Full stack trace from the hung child looks like: #0 __internal_syscall_cancel (a1=<optimized out>, a2=93824996936336, a3=4096, a4=a4@entry=0, a5=a5@entry=0, a6=a6@entry=0, nr=nr@entry=64) at ./nptl/cancellation.c:44 #1 0x00007ffff7d7925c in __syscall_cancel (a1=<optimized out>, a2=<optimized out>, a3=<optimized out>, a4=a4@entry=0, a5=a5@entry=0, a6=a6@entry=0, nr=nr@entry=64) at ./nptl/cancellation.c:75 #2 0x00007ffff7decdd4 in __GI___libc_write (fd=<optimized out>, buf=<optimized out>, nbytes=<optimized out>) at ../sysdeps/unix/sysv/linux/write.c:26 #3 0x0000555555630354 in o_stream_file_writev (fstream=0x5555559c5bc0, iov=0x7ffffffea398, iov_count=<optimized out>, error_r=0x7ffffffea330) at ./src/lib/ostream-file.c:171 #4 0x0000555555630ea0 in o_stream_file_writev_full (fstream=fstream@entry=0x5555559c5bc0, iov=iov@entry=0x7ffffffea398, iov_count=iov_count@entry=1) at ./src/lib/ostream-file.c:256 #5 0x0000555555631254 in buffer_flush (fstream=fstream@entry=0x5555559c5bc0) at ./src/lib/ostream-file.c:356 #6 0x0000555555631e08 in o_stream_file_flush (stream=0x5555559c5bc0) at ./src/lib/ostream-file.c:443 #7 o_stream_file_sendv (stream=0x5555559c5bc0, iov=0x7ffffffea458, iov_count=2) at ./src/lib/ostream-file.c:645 #8 0x000055555562b288 in o_stream_sendv_int (stream=0x5555559c5c60, iov=<optimized out>, iov_count=<optimized out>, overflow_r=0x7ffffffea448) at ./src/lib/ostream.c:335 #9 0x0000555555638690 in o_stream_sendv (stream=<optimized out>, iov=0x7ffffffea458, iov_count=2) at ./src/lib/ostream.c:360 #10 o_stream_multiplex_send_stream (mstream=0x5555559c6320, channel=0x5555559c4fe0) at ./src/lib/ostream-multiplex.c:226 #11 o_stream_multiplex_sendv (mstream=0x5555559c6320) at ./src/lib/ostream-multiplex.c:319 #12 o_stream_multiplex_sendv (mstream=0x5555559c6320) at ./src/lib/ostream-multiplex.c:275 #13 0x0000555555638d98 in o_stream_multiplex_ochannel_sendv (stream=0x5555559c4fe0, iov=<optimized out>, iov_count=<optimized out>) at ./src/lib/ostream-multiplex.c:461 #14 0x000055555562b288 in o_stream_sendv_int (stream=stream@entry=0x5555559c5080, iov=iov@entry=0x7ffffffea568, iov_count=iov_count@entry=1, overflow_r=overflow_r@entry=0x7ffffffea560) at ./src/lib/ostream.c:335 #15 0x0000555555630ab8 in o_stream_sendv (stream=0x5555559c5080, iov=0x7ffffffea568, iov_count=1) at ./src/lib/ostream.c:360 #16 io_stream_copy (outstream=0x5555559c5080, instream=0x5555559c6f70) at ./src/lib/ostream.c:549 #17 0x00005555556305f0 in o_stream_send_istream (outstream=0x5555559c5080, instream=0x5555559c6f70) at ./src/lib/ostream.c:454 #18 0x00005555555bf8e4 in test_stream_backpressure_child (context=<optimized out>) at ./src/lib/test-ostream-multiplex.c:730 #19 0x00005555555eb04c in test_subprocess_child (func=0x5555555bf7f0 <test_stream_backpressure_child>, context=0x0, continue_test=true) at ../lib-test/test-subprocess.c:72 #20 test_subprocess_fork (func=0x5555555bf7f0 <test_stream_backpressure_child>, context=0x0, continue_test=true) at ../lib-test/test-subprocess.c:111 #21 0x00005555555c18a8 in test_ostream_multiplex_stream_backpressure () at ./src/lib/test-ostream-multiplex.c:768 #22 test_ostream_multiplex () at ./src/lib/test-ostream-multiplex.c:868 #23 0x00005555555de9f4 in test_run_named_funcs (tests=0x5555559a9500 <test_functions>, match=match@entry=0x7ffffffebca9 "ostream") at ../lib-test/test-common.c:501 #24 0x00005555555e4320 in test_run_named_with_fatals (match=0x7ffffffebca9 "ostream", tests=<optimized out>, fatals=0x5555559a93c0 <fatal_functions>) at ../lib-test/test-common.c:588 #25 0x00007ffff7d0dd08 in __libc_start_call_main (main=main@entry=0x55555557d050 <main>, argc=argc@entry=3, argv=argv@entry=0x7ffffffeb9e8) at ../sysdeps/nptl/libc_start_call_main.h:59 #26 0x00007ffff7d0de60 in __libc_start_main_impl (main=0x55555557d050 <main>, argc=3, argv=0x7ffffffeb9e8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=<optimized out>) at ../csu/libc-start.c:360 #27 0x000055555557d280 in _start () Diff to work around this issue: diff --git a/src/lib/test-ostream-multiplex.c b/src/lib/test-ostream-multiplex.c index 59dcf02ed1..d83b801f24 100644 --- a/src/lib/test-ostream-multiplex.c +++ b/src/lib/test-ostream-multiplex.c @@ -715,7 +715,7 @@ static int test_stream_backpressure_child(void *context ATTR_UNUSED) /* Small parent buffer so avail reaches 0 quickly once the socket fills; this is the congested state where the backpressure fix matters. */ - struct ostream *parent = o_stream_create_fd(fd[1], 4096); + struct ostream *parent = o_stream_create_fd(fd[1], 8192); o_stream_set_no_error_handling(parent, TRUE); struct ostream *chan0 = o_stream_create_multiplex(parent, SIZE_MAX, OSTREAM_MULTIPLEX_FORMAT_STREAM);