iouring

package
v1.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 6, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package iouring implements an engine backed by Linux io_uring.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BufferGroup

type BufferGroup struct {
	// contains filtered or unexported fields
}

BufferGroup manages a group of provided buffers for multishot recv. This is the legacy PROVIDE_BUFFERS approach, kept for fallback on older kernels.

func NewBufferGroup

func NewBufferGroup(ring *Ring, groupID uint16, count, size int) (*BufferGroup, error)

NewBufferGroup creates and registers a provided buffer group with the ring.

func (*BufferGroup) AvailableCount

func (bg *BufferGroup) AvailableCount() int

AvailableCount returns the number of available buffers.

func (*BufferGroup) GetBuffer

func (bg *BufferGroup) GetBuffer(bufID uint16) []byte

GetBuffer returns the buffer for the given buffer ID.

func (*BufferGroup) ReturnBuffer

func (bg *BufferGroup) ReturnBuffer(ring *Ring, bufID uint16) error

ReturnBuffer returns a buffer to the group and re-provides it to the kernel.

type BufferRing added in v1.1.0

type BufferRing struct {
	// contains filtered or unexported fields
}

BufferRing manages a ring-mapped provided buffer group (IORING_REGISTER_PBUF_RING). Both ring and buffer memory are allocated via mmap outside the Go heap to avoid inflating GC accounting.

func NewBufferRing added in v1.1.0

func NewBufferRing(ring *Ring, groupID uint16, count, size int) (*BufferRing, error)

NewBufferRing creates and registers a ring-mapped provided buffer group. The buffers are mmap'd outside the Go heap. count must be a power of 2.

func (*BufferRing) Close added in v1.1.0

func (br *BufferRing) Close(ring *Ring)

Close unregisters the buffer ring and releases mmap'd memory.

func (*BufferRing) GetBuffer added in v1.1.0

func (br *BufferRing) GetBuffer(bufID uint16, dataLen int) []byte

GetBuffer returns a slice of the buffer for the given buffer ID and data length.

func (*BufferRing) PublishBuffers added in v1.1.0

func (br *BufferRing) PublishBuffers()

PublishBuffers makes all pushed entries visible to the kernel with a single atomic store. Call after one or more PushBuffer calls.

func (*BufferRing) PushBuffer added in v1.1.0

func (br *BufferRing) PushBuffer(bufID uint16)

PushBuffer queues a buffer for return without publishing to the kernel. Call PublishBuffers once after batching multiple PushBuffer calls.

func (*BufferRing) ReturnBuffer added in v1.1.0

func (br *BufferRing) ReturnBuffer(bufID uint16)

ReturnBuffer returns a buffer to the ring by pushing a new entry and publishing the updated tail. Must be called after the buffer data has been fully consumed.

type Engine

type Engine struct {
	// contains filtered or unexported fields
}

Engine implements the io_uring-based I/O engine.

func New

func New(cfg resource.Config, handler stream.Handler) (*Engine, error)

New creates a new io_uring engine.

func (*Engine) Addr

func (e *Engine) Addr() net.Addr

Addr returns the bound listener address.

func (*Engine) Listen

func (e *Engine) Listen(ctx context.Context) error

Listen starts the io_uring engine and blocks until context is canceled.

func (*Engine) Metrics

func (e *Engine) Metrics() engine.EngineMetrics

Metrics returns a snapshot of engine metrics.

func (*Engine) PauseAccept added in v0.3.0

func (e *Engine) PauseAccept() error

PauseAccept stops accepting new connections while keeping existing ones alive.

func (*Engine) ResumeAccept added in v0.3.0

func (e *Engine) ResumeAccept() error

ResumeAccept starts accepting new connections again. Wakes any suspended workers so they re-create listen sockets.

func (*Engine) Shutdown

func (e *Engine) Shutdown(_ context.Context) error

Shutdown gracefully shuts down the engine.

func (*Engine) Type

func (e *Engine) Type() engine.EngineType

Type returns the engine type.

type Ring

type Ring struct {
	// contains filtered or unexported fields
}

Ring is an io_uring instance with mmap'd SQ/CQ rings and SQE array.

func NewRing

func NewRing(entries uint32, flags uint32, sqPollIdle uint32) (*Ring, error)

NewRing creates a new io_uring instance. sqPollIdle sets the kernel SQPOLL thread idle timeout in milliseconds (only used with IORING_SETUP_SQPOLL).

func NewRingCPU added in v1.1.0

func NewRingCPU(entries uint32, flags uint32, sqPollIdle uint32, cpuID int) (*Ring, error)

NewRingCPU creates a new io_uring instance with optional SQPOLL CPU affinity. If cpuID >= 0 and SQPOLL is enabled, IORING_SETUP_SQ_AFF is set to pin the kernel's SQPOLL thread to the specified CPU, ensuring NUMA-local processing.

func (*Ring) BeginCQ added in v1.1.0

func (r *Ring) BeginCQ() (head, tail uint32)

BeginCQ returns the current CQ head and tail for batch processing. Under SINGLE_ISSUER, cqHead is a plain load (we own it).

func (*Ring) ClearPending added in v1.1.0

func (r *Ring) ClearPending()

ClearPending resets the pending counter without issuing a syscall. Used with SQPOLL where the kernel thread submits SQEs automatically.

func (*Ring) Close

func (r *Ring) Close() error

Close closes the ring and unmaps memory.

func (*Ring) EndCQ added in v1.1.0

func (r *Ring) EndCQ(newHead uint32)

EndCQ advances the CQ head to newHead with a single atomic store.

func (*Ring) GetSQE

func (r *Ring) GetSQE() unsafe.Pointer

GetSQE returns a pointer to the next available SQE, or nil if the ring is full.

func (*Ring) Pending added in v1.1.0

func (r *Ring) Pending() uint32

Pending returns the number of SQEs submitted but not yet sent to the kernel.

func (*Ring) RegisterFiles added in v1.1.0

func (r *Ring) RegisterFiles(count int) error

RegisterFiles pre-registers a fixed file table with the kernel. Each entry is initialized to -1 (empty). Use UpdateFixedFile to install FDs into slots.

func (*Ring) RegisterPbufRing added in v1.1.0

func (r *Ring) RegisterPbufRing(groupID uint16, entries uint32, ringAddr unsafe.Pointer) error

RegisterPbufRing registers a ring-mapped provided buffer ring with the kernel. The ring memory is allocated by the caller via mmap and passed in ringAddr. The caller is responsible for munmapping the ring memory after unregistering.

func (*Ring) SQNeedWakeup added in v1.1.0

func (r *Ring) SQNeedWakeup() bool

SQNeedWakeup returns true if the SQPOLL kernel thread went idle and needs a wakeup via WakeupSQPoll() to resume submitting SQEs.

func (*Ring) Submit

func (r *Ring) Submit() (int, error)

Submit submits pending SQEs to the kernel.

func (*Ring) SubmitAndWait

func (r *Ring) SubmitAndWait() error

SubmitAndWait submits pending SQEs and waits for at least one CQE.

func (*Ring) SubmitAndWaitTimeout

func (r *Ring) SubmitAndWaitTimeout(timeout time.Duration) error

SubmitAndWaitTimeout submits pending SQEs and waits for at least one CQE, with a timeout. Returns nil on timeout (ETIME) or EINTR.

func (*Ring) UnregisterPbufRing added in v1.1.0

func (r *Ring) UnregisterPbufRing(groupID uint16) error

UnregisterPbufRing unregisters a ring-mapped provided buffer ring.

func (*Ring) UpdateFixedFile added in v1.1.0

func (r *Ring) UpdateFixedFile(slot int, fd int) error

UpdateFixedFile installs or removes a file descriptor in a fixed file slot. Set fd to -1 to clear a slot.

func (*Ring) WaitCQE

func (r *Ring) WaitCQE() error

WaitCQE waits for at least one CQE to become available.

func (*Ring) WaitCQETimeout added in v1.1.0

func (r *Ring) WaitCQETimeout(timeout time.Duration) error

WaitCQETimeout waits for at least one CQE without submitting any SQEs. Used by SQPOLL workers where the kernel thread handles submission. Returns nil on timeout (ETIME) or EINTR.

func (*Ring) WakeupSQPoll

func (r *Ring) WakeupSQPoll() error

WakeupSQPoll wakes up the SQPOLL thread if it went to sleep.

type SendZCProbeResult added in v1.1.0

type SendZCProbeResult int

SendZCProbeResult describes the outcome of the SEND_ZC runtime probe.

const (
	// SendZCUnsupported means the kernel doesn't support the SEND_ZC opcode.
	SendZCUnsupported SendZCProbeResult = iota
	// SendZCBroken means the kernel accepts SEND_ZC but the notification CQE
	// never arrives (e.g., ENA driver DMA completion bug).
	SendZCBroken
	// SendZCCopyFallback means SEND_ZC works but the kernel copies data instead
	// of using DMA zero-copy. The notification arrives correctly. This happens
	// on loopback or NICs without scatter-gather DMA. SEND_ZC is functional
	// but provides no performance benefit over regular SEND.
	SendZCCopyFallback
	// SendZCTrueZeroCopy means SEND_ZC uses real DMA zero-copy. The notification
	// arrives and reports actual zero-copy usage. This is the optimal case.
	SendZCTrueZeroCopy
)

func (SendZCProbeResult) String added in v1.1.0

func (r SendZCProbeResult) String() string

type TierStrategy

type TierStrategy interface {
	Tier() engine.Tier
	SetupFlags() uint32
	PrepareAccept(ring *Ring, listenFD int)
	PrepareRecv(ring *Ring, fd int, buf []byte)
	PrepareSend(ring *Ring, fd int, buf []byte, linked bool)
	SupportsProvidedBuffers() bool
	SupportsMultishotAccept() bool
	SupportsMultishotRecv() bool
	SupportsFixedFiles() bool
	SupportsSendZC() bool
	SQPollIdle() uint32
}

TierStrategy configures io_uring behavior based on detected capabilities.

func SelectTier

func SelectTier(profile engine.CapabilityProfile, sqPollIdle time.Duration) TierStrategy

SelectTier returns the highest available tier strategy for the given profile. sqPollIdle is the objective-specific SQPOLL thread idle timeout; if zero, defaults to 2000ms.

type Worker

type Worker struct {
	// contains filtered or unexported fields
}

Worker is a per-core io_uring event loop.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL