wired
libc-free QUIC/HTTP3 SDK in C for x86_64-linux
Loading...
Searching...
No Matches
xsksetup.h File Reference

AF_XDP socket setup: socket(2)/setsockopt(2)/getsockopt(2)/mmap(2)/bind(2) sequence that turns a raw AF_XDP fd into four ready-to-poll SPSC rings (fill/comp/rx/tx) over one UMEM. More...

Go to the source code of this file.

Data Structures

struct  xsk_cfg
 Caller-supplied configuration for one AF_XDP socket. More...
struct  xsk
 One open AF_XDP socket: the fd, its UMEM, the four rings, and the mmap regions backing them (kept so xsksetup_close can munmap them). More...

Macros

#define XSKSETUP_UMEM_FRAMES   1024u
 Fixed capacity: one UMEM frame per fill/comp/rx/tx ring entry slot count below, matching xskumem's XSKUMEM_FRAMES (1024 frames of 2048B = 2MiB).
#define XSKSETUP_FRAME_SIZE   2048u
 Byte size of one UMEM frame, matching xskumem's XSKUMEM_FRAME_SIZE.
#define XSKSETUP_UMEM_LEN   ((u64)XSKSETUP_UMEM_FRAMES * XSKSETUP_FRAME_SIZE)
 Total UMEM byte length.
#define XSKSETUP_RX_POOL_FRAMES   256u
 Number of UMEM frames (0..XSKSETUP_RX_POOL_FRAMES) reserved for the kernel's fill/RX side (xsksetup_prime_fill).
#define XSKSETUP_RING_ENTRIES   64u
 Entries per ring (fill/comp/rx/tx), must be a power of two.

Functions

i64 xsksetup_open (xsk *x, const xsk_cfg *cfg)
 Open one AF_XDP socket bound to cfg->ifindex/queue_id: socket -> UMEM anonymous mmap -> XDP_UMEM_REG -> ring size setsockopts -> XDP_MMAP_OFFSETS -> mmap the four rings -> xskring_init each -> bind -> prime the fill ring with all RX-pool frames.
void xsksetup_close (xsk *x)
 Tear down x: munmap every ring region and the UMEM, close the fd.
i64 xsksetup_kick_tx (i64 fd)
 Wake the kernel to service the TX ring (sendto with no data, matching the driver's XDP_COPY bind mode which needs an explicit kick).
i64 xsksetup_stats (i64 fd, u64 out[6])
 Read XDP_STATISTICS into out[6]: rx_dropped, rx_invalid_descs, tx_invalid_descs, rx_ring_full, rx_fill_ring_empty_descs, tx_ring_empty_descs (linux/if_xdp.h struct xdp_statistics order).

Detailed Description

AF_XDP socket setup: socket(2)/setsockopt(2)/getsockopt(2)/mmap(2)/bind(2) sequence that turns a raw AF_XDP fd into four ready-to-poll SPSC rings (fill/comp/rx/tx) over one UMEM.

Everything above this layer (ring op / frame parse / bpf) is pure and already tested; this file is only the syscall plumbing that wires those parts to the kernel.

Macro Definition Documentation

◆ XSKSETUP_RX_POOL_FRAMES

#define XSKSETUP_RX_POOL_FRAMES   256u

Number of UMEM frames (0..XSKSETUP_RX_POOL_FRAMES) reserved for the kernel's fill/RX side (xsksetup_prime_fill).

The remainder (XSKSETUP_UMEM_FRAMES - XSKSETUP_RX_POOL_FRAMES) is the server's TX pool (srvxdp's SRVXDP_TXPOOL_FRAMES). Skewed toward TX: an HTTP/3 server mostly transmits (response bodies) and rarely needs many RX frames in flight at once.

◆ XSKSETUP_UMEM_FRAMES

#define XSKSETUP_UMEM_FRAMES   1024u

Fixed capacity: one UMEM frame per fill/comp/rx/tx ring entry slot count below, matching xskumem's XSKUMEM_FRAMES (1024 frames of 2048B = 2MiB).

A 1MB file at a ~1400B QUIC packet size needs ~750 in-flight TX frames; the prior 128-frame UMEM (64 TX) stalled on txpool exhaustion well before that (observed as xdp_statistics.tx_ring_empty_descs = 14352 on a real VPS run). 1024 gives headroom above that without growing the mmap past a few MiB.

◆ XSKSETUP_UMEM_LEN

#define XSKSETUP_UMEM_LEN   ((u64)XSKSETUP_UMEM_FRAMES * XSKSETUP_FRAME_SIZE)

Total UMEM byte length.

Cast to u64 before multiplying: both operands are u32, and a plain u32*u32 product then gets implicitly widened when used as a u64 length/offset (bugprone-implicit-widening-of-multiplication-result). The current constants fit in 32 bits either way, but computing the product in the target width is what the mmap length/UMEM offset math needs.

Function Documentation

◆ xsksetup_close()

void xsksetup_close ( xsk * x)

Tear down x: munmap every ring region and the UMEM, close the fd.

Safe to call twice (a second call is a no-op: fd is left at -1 after the first).

◆ xsksetup_open()

i64 xsksetup_open ( xsk * x,
const xsk_cfg * cfg )

Open one AF_XDP socket bound to cfg->ifindex/queue_id: socket -> UMEM anonymous mmap -> XDP_UMEM_REG -> ring size setsockopts -> XDP_MMAP_OFFSETS -> mmap the four rings -> xskring_init each -> bind -> prime the fill ring with all RX-pool frames.

On any failure, everything allocated so far is unwound and a negative errno is returned.

Parameters
xzero-initialized output; filled in on success
cfgifindex/queue_id/bind_flags
Returns
0 on success, or a negative errno