Add FiberScheduler::splice - #120
Open
alexey-milovidov wants to merge 1 commit into
Open
Conversation
Submit IORING_OP_SPLICE in the same blocking and async forms as read, write and accept. Splice moves bytes between two descriptors inside the kernel; as in splice(2) one of them must be a pipe, so a caller relaying a stream between two sockets forwards it through an intermediate pipe, with no user-space copy and no dependence on a user-space buffer size. A zero in bytesSpliced means the source reached end of input. The test relays a payload from one socket to another through a pipe over both forms of the call and checks the end-of-input result.
1 task
vadimskipin
approved these changes
Aug 14, 2026
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.
FiberScheduler::splicesubmitsIORING_OP_SPLICEin the same blocking and async forms asread,writeandaccept, so a fiber can move bytes between two descriptors entirely inside the kernel. As withsplice(2)one of the two descriptors must be a pipe, which means a relay between two sockets goes socket -> pipe -> socket and never copies the payload into user space.This is what the ClickHouse proxy uses to forward plaintext connections: ClickHouse/ClickHouse#110105. With the copy relay the bulk HTTP throughput of the proxy was bounded by the user-space buffer size (845 MB/s at a 16 KiB buffer); after switching those legs to
spliceit reaches ~5 GB/s, matching a direct connection to the backend, and the added per-query latency is unchanged. TLS-terminating legs keep the copy path since their bytes have to be decrypted in user space.The test relays a payload from one socket to another through a pipe, over the blocking overload for the first leg and the async one for the second, and checks that a source whose peer has shut down reports end of input as zero bytes moved.
./bb test -R FiberIopasses locally in the debug build and under all four sanitizers (address, memory, thread, undefined).The change is currently carried on the
add-splice-opbranch, which the ClickHouse pull request pins; once this is merged andclickhouse-publicis rebuilt, that pull request will re-pin the submodule to the generated commit.