feat(fast_io): refuse SQPOLL when mmap reader is active#4069
Merged
Conversation
Adds a defensive configuration-time check on IoUringConfig::build_ring that disables SQPOLL when the caller has signalled that an mmap-backed basis reader is live on the same transfer plan. Pairing IORING_SETUP_SQPOLL with a file-backed mmap region is a known kernel hazard: the SQPOLL kthread services SQEs without the user mm context, so cold-page faults on mapped pages bounce to task_work on the original task (deadlock loop on pre-6.x kernels) and concurrent truncation surfaces as in-kernel SIGBUS. The new mmap_basis_active field on IoUringConfig defaults to false. When flipped to true, build_ring emits a debug_log warning, sets the existing SQPOLL_FALLBACK flag, and falls back to a regular ring. Graceful degrade rather than transfer failure. Updates docs/audits/io-uring-sqpoll-mmap-interaction.md to mark the S1 caveat resolved with implementation reference.
oferchen
added a commit
that referenced
this pull request
May 18, 2026
Adds a defensive configuration-time check on IoUringConfig::build_ring that disables SQPOLL when the caller has signalled that an mmap-backed basis reader is live on the same transfer plan. Pairing IORING_SETUP_SQPOLL with a file-backed mmap region is a known kernel hazard: the SQPOLL kthread services SQEs without the user mm context, so cold-page faults on mapped pages bounce to task_work on the original task (deadlock loop on pre-6.x kernels) and concurrent truncation surfaces as in-kernel SIGBUS. The new mmap_basis_active field on IoUringConfig defaults to false. When flipped to true, build_ring emits a debug_log warning, sets the existing SQPOLL_FALLBACK flag, and falls back to a regular ring. Graceful degrade rather than transfer failure. Updates docs/audits/io-uring-sqpoll-mmap-interaction.md to mark the S1 caveat resolved with implementation reference.
oferchen
added a commit
that referenced
this pull request
May 18, 2026
Adds a defensive configuration-time check on IoUringConfig::build_ring that disables SQPOLL when the caller has signalled that an mmap-backed basis reader is live on the same transfer plan. Pairing IORING_SETUP_SQPOLL with a file-backed mmap region is a known kernel hazard: the SQPOLL kthread services SQEs without the user mm context, so cold-page faults on mapped pages bounce to task_work on the original task (deadlock loop on pre-6.x kernels) and concurrent truncation surfaces as in-kernel SIGBUS. The new mmap_basis_active field on IoUringConfig defaults to false. When flipped to true, build_ring emits a debug_log warning, sets the existing SQPOLL_FALLBACK flag, and falls back to a regular ring. Graceful degrade rather than transfer failure. Updates docs/audits/io-uring-sqpoll-mmap-interaction.md to mark the S1 caveat resolved with implementation reference.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
IoUringConfig::build_ringthat disablesIORING_SETUP_SQPOLLwhen the caller has signalled an mmap-backed basis reader is live on the same transfer plan. Closes Update Homebrew formula for v3.4.1-rust #2158.mmcontext, so cold-page faults on mapped pages bounce throughtask_workon the original task (deadlock loop on pre-6.x kernels), and concurrent truncation surfaces as in-kernelSIGBUS. Seedocs/audits/io-uring-sqpoll-mmap-interaction.mdplus companion auditsmmap-iouring-sqpoll-pagefaults.mdandio_uring_sqpoll_mmap_pagefault.md.IoUringConfig::mmap_basis_activefield defaults tofalse. Whentrue,build_ringemits adebug_log!(Io, 1, ...)warning, sets the existingSQPOLL_FALLBACKflag, and falls back to a regular ring rather than failing the transfer.docs/audits/io-uring-sqpoll-mmap-interaction.mdto mark the S1 caveat resolved with implementation reference.Why this is defensive, not a bug fix
Today's wired paths already avoid the hazard:
DeltaApplicatorforcesBufferedMapfor the basis file when its writer is io_uring-backed, and no preset turns SQPOLL on. The check closes the audit's "OK-with-caveat" gap: a future caller that flipssqpoll = truealongside anMmapStrategybasis is now refused at config time, before any SQE reaches the kernel.Test plan
default_config_mmap_basis_inactiveconfirms the field defaults tofalseacrossDefault,for_large_files,for_small_files.build_ring_sqpoll_with_small_files_no_mmap_keeps_requestconfirms SQPOLL stays enabled (or falls back for permission reasons) when no mmap basis is active.build_ring_sqpoll_with_mmap_basis_disables_sqpollconfirms SQPOLL is refused andsqpoll_fell_back()returnstruewhenmmap_basis_active: true.build_ring_no_sqpoll_with_mmap_basis_no_warningconfirms the flag is inert when SQPOLL was never requested.