Re: BUG #19792: BUG: Deadlock between WaitIO and read-stream look-ahead under io_method=io_uring (18.6)

From: shihao zhong <zhong950419(at)gmail(dot)com>
To: barton(dot)tomas(at)gmail(dot)com
Cc: pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19792: BUG: Deadlock between WaitIO and read-stream look-ahead under io_method=io_uring (18.6)
Date: 2026-10-25 18:31:11
Message-ID: CAGRkXqQ1MH7Okf7M7pxShC6cBgNL5jhVbj7Pwz-uVAGw9qcOfA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi Thomas,

Thanks for the report.

I'm starting to learn AIO and have no Linux machine for io_uring, so I
could not
reproduce this with a real workload. From the code, I think it goes
like this.

t1 A: an INSERT splitting leaf 627 holds its lock.
t2 B: autovacuum's btree scan starts a look-ahead read of 628.
BM_IO_IN_PROGRESS is set, but io_wref is not yet.
t3 A: gets 628 from the FSM. WaitIO() sees no io_wref, so it
sleeps on the buffer CV.
t4 B: stages the IO and sets io_wref, but does not wake A.
t5 B: waits for the lock on 627 that A holds.
t6 A and B wait on each other forever.

With io_uring, only the owner or a backend that waits through io_wref
reaps the completion, so nobody reaps it. [1] only fixes waits
through io_wref, and A never gets there.

0001 is Thomas Munro's patch from [1]. A woken A can find the IO
still staged, and waits on submit_cv.
0002 wakes the buffer CV once io_wref is set. It also wakes
submit_cv after synchronous execution, which 0001 misses.

Draft attached. Could someone check them?

[1]
https://www.postgresql.org/message-id/CA%2BhUKG%2BmZYrSdnhk-XrBYO18H829K77S9gMKUsykOiTJtqB43g%40mail.gmail.com

Thanks,
Shihao

Attachment Content-Type Size
v3-0001-aio-Fix-pgaio_io_wait-for-staged-IOs.patch application/octet-stream 5.1 KB
v3-0002-aio-Fix-lost-wakeups-when-waiting-for-another-bac.patch application/octet-stream 2.1 KB

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message BHUVAN CHILUKUTI 2026-10-25 19:55:54 Re: first_value()/nth_value() with IGNORE NULLS loop forever (EXCLUDE GROUP/TIES, frame past partition end, no ORDER BY)
Previous Message shihao zhong 2026-10-25 16:04:37 Re: first_value()/nth_value() with IGNORE NULLS loop forever (EXCLUDE GROUP/TIES, frame past partition end, no ORDER BY)