Zero-Syscall Kernel I/O via io_uring (SQPOLL)
Ship provides raw, bare-metal built-in function wrappers for the Linux io_uring subsystems and memory mapping system calls. This enables high-performance, asynchronous, zero-syscall user-space I/O.
1. Exposed Compiler Built-ins
The following low-level built-in primitives are now wired directly into the compiler, lowering to their respective Linux x86_64 system calls:
sys_io_uring_setup
Initializes a new io_uring instance.
entries: Size of the submission and completion queues.
* params: Memory pointer to the io_uring_params structural setup.
* Returns: File descriptor of the io_uring instance, or -1 on error.
sys_io_uring_enter
Initiates and completes I/O operations.
* Syscall ID: 426 * Parameters: *fd: io_uring ring file descriptor.
* to_submit: Number of entries to submit.
* min_complete: Minimum completed operations to wait for.
* flags: Completion modifiers (e.g. IORING_ENTER_GETEVENTS).
sys_io_uring_register
Registers user-space buffers or files for kernel polling optimization.
* Syscall ID: 427sys_mmap
Maps memory pages shared between user space and kernel space.
* Syscall ID: 92. Implementing Zero-Syscall I/O (SQPOLL)
To bypass the context-switching penalty of system calls entirely:
- Enable SQPOLL Mode: Set the
IORING_SETUP_SQPOLLflag inside yourio_uring_paramsstruct before callingsys_io_uring_setup. - Kernel Thread Loop: The kernel spawns a dedicated background thread that continuously polls the shared Submission Queue (SQ).
- Queue Updates: In user-space, write requests (e.g., file reads, packet sends) straight to the submission ring memory mapped via
sys_mmap, and increment the queue's tail pointer. - Result Collection: Read results from the Completion Queue (CQ) buffers.
This lock-less ring buffer flow entirely avoids syscall transitions, context switches, and TLB flushes, achieving maximum hardware throughput.