pg.ddx.io  pgsql-committers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Andres Freund <andres@anarazel.de>
To: pgsql-committers@lists.postgresql.org
Subject: pgsql: aio: Add missing memory barrier when waiting for IO handle
Date: Mon, 16 Jun 2025 17:12:08 +0000
Message-ID: <E1uRDNQ-001wmO-1q@gemulon.postgresql.org> (raw)

aio: Add missing memory barrier when waiting for IO handle

Previously there was no memory barrier enforcing correct memory ordering when
waiting for a free IO handle. However, in the much more common case of waiting
for IO to complete, memory barriers already were present.

On strongly ordered architectures like x86 this had no negative consequences,
but on some armv8 hardware (observed on Apple hardware), it was possible for
the update, in the IO worker, to PgAioHandle->state to become visible before
->distilled_result becoming visible, leading to rather confusing assertion
failures. The failures were rare enough that the bug sometimes took days to
reproduce when running 027_stream_regress in a loop.

Once finally debugged, it was easy enough to come up with a much quicker
repro: Trigger a lot of very fast IO by limiting io_combine_limit to 1 and
ensure that we always have to wait for a free handle by setting
io_max_concurrency to 1. Triggering lots of concurrent seqscans in that setup
triggers the issue within seconds.

One reason this was hard to debug was that the assertion failure most commonly
happened in WaitReadBuffers(), rather than in the AIO subsystem itself. The
assertions added in this commit make problems like this easier to understand.

Also add a comment to the IO worker explaining that we rely on the lwlock
acquisition for correct memory ordering.

I think it'd be good to add a tap test that stress tests buffer IO, but that's
material for a separate patch.

Thanks a lot to Alexander and Konstantin for all the debugging help.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
Reported-by: Alexander Lakhin <exclusion@gmail.com>
Investigated-by: Andres Freund <andres@anarazel.de>
Investigated-by: Alexander Lakhin <exclusion@gmail.com>
Investigated-by: Konstantin Knizhnik <knizhnik@garret.ru>
Discussion: https://postgr.es/m/2dkz7azclpeiqcmouamdixyn5xhlzy4rvikxrbovyzvi6rnv5c@pz7o7osv2ahf

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/e9a3615a5224236917af161d9b6a55ba8f129b4d

Modified Files
--------------
src/backend/storage/aio/aio.c           | 17 +++++++++++++++++
src/backend/storage/aio/aio_callback.c  |  7 +++++++
src/backend/storage/aio/method_worker.c |  7 ++++++-
3 files changed, 30 insertions(+), 1 deletion(-)



Message-ID: <E1uRDNQ-001wmO-1q@gemulon.postgresql.org>
Permalink:  ../E1uRDNQ-001wmO-1q@gemulon.postgresql.org/
Also on:    postgresql.org/message-id/E1uRDNQ-001wmO-1q@gemulon.postgresql.org

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-committers@postgresql.org
  Cc: andres@anarazel.de, pgsql-committers@lists.postgresql.org
  Subject: Re: pgsql: aio: Add missing memory barrier when waiting for IO handle
  In-Reply-To: <E1uRDNQ-001wmO-1q@gemulon.postgresql.org>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox