Re: BUG #19796: io_uring crashes with specific kernel/liburing versions + io_max_concurrency due to rings overlap

From: Andres Freund <andres(at)anarazel(dot)de>
To: Andrey Rachitskiy <pl0h0yp1(at)gmail(dot)com>
Cc: exclusion(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19796: io_uring crashes with specific kernel/liburing versions + io_max_concurrency due to rings overlap
Date: 2026-10-26 13:27:28
Message-ID: sdubmew6ie53hhijyavipv2nawgjwmpwzvl2dvftxkghtcxb5f@2fzx7vey6k7l
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,

On 2026-10-26 13:27:28 +0500, Andrey Rachitskiy wrote:
> Thanks for the report.
>
> PostgreSQL stores one io_uring ring per backend in one shared-memory
> buffer. The next ring starts at the byte count io_uring_queue_init_mem()
> returns. Before liburing 2.7 that count leaves out the io_rings header. The
> kernel's ring is longer, and the next ring overlaps its tail.
>
> The real length is in the parameters the kernel fills in. cq_off.cqes is
> where the CQE array starts, and that offset already includes the header.
> Add the CQE array, align to the cache line, then add the SQ index array if
> the kernel created one. On a 1024-entry ring the missing part is 64 bytes.
> With liburing 2.5 it is the end of the SQ index array.
> Liburing 2.6 has no index array, and those 64 bytes are the end of the CQE
> array. Liburing 2.7 includes the header, so the returned count is already
> enough.
> A fixed extra 64 bytes would also move a correct liburing, and the next
> ring would no longer start on a page. The kernel rejects such an address.
> The patch keeps whichever is further, the computed end or liburing's count,
> and rounds that up to a page. If liburing's count is already past that end,
> the reservation stays as it is. Without io_uring_queue_init_mem() and
> IORING_SETUP_NO_MMAP this code is not compiled. Each ring still gets its
> own mapping.
>
> Checked with io_method=io_uring and io_max_concurrency=1024. liburing 2.5
> reported 102400 bytes per ring.
> Unpatched, pgbench -c 4 hit both "io_uring submit submitted only 0 of 1"
> and Assert(ioh->state == PGAIO_HS_SUBMITTED).
> Patched, the server reserved 106496 bytes and the same run finished.
> On liburing 2.7 the reservation stayed 102400 bytes and the run finished.
>
> Alexander, please try the builds you still have. liburing 2.5, 2.6 and 2.7,
> on both machines from the report.
> I only ran 2.5 and 2.7 on x86_64.

I'd really appreciate if you stopped copy-pasting bug reports to an LLM an
then copying the answer back. We all have access to this wondrous copy-paste
magic and most of us have access to LLMs. All this does is to further increase
the noise level of the lists which is already very high.

It's useful to analyze bugs, but it does require actual analysis and the
messages need to be actually readable stuff, rather than LLM goop.

Greetings,

Andres Freund

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Andres Freund 2026-10-26 13:31:48 Re: BUG #19796: io_uring crashes with specific kernel/liburing versions + io_max_concurrency due to rings overlap
Previous Message Hayato Kuroda (Fujitsu) 2026-10-26 13:25:22 RE: Streaming decoding fails with "unexpected table_index_fetch_tuple call during logical decoding" when a relation has a TOASTed conbin (follow-up to BUG #18641)