io_uring_register_buf_ring(3)
π io_uring_register_buf_ring β register buffer ring for provided buffers π
okay bestie, this one lives in the liburing Manual and it's literally the β¨glow-upβ¨ move for feeding buffers to your ring. let's get into it π«Ά
πΈ SYNOPSIS πΈ
#include <liburing.h>
int io_uring_register_buf_ring(struct io_uring *ring,
struct io_uring_buf_reg *reg,
unsigned int flags);
β¨ DESCRIPTION β¨
so io_uring_register_buf_ring(3) registers a shared buffer ring that you're gonna use with provided buffers. here's the vibe: for the request types that support it, provided buffers get handed to the ring, and then a request picks one when it's ready to receive data β but only if it has IOSQE_BUFFER_SELECT set in the SQE flags. iykyk π
and the way this slays is twofold:
- you get clear ownership of the buffer lifetime π
- and you can have more read/receive-type operations in flight than you have buffers π₯
obsessed, honestly.
the reg argument has to be filled in with the right info. it looks like this:
struct io_uring_buf_reg {
__u64 ring_addr;
__u32 ring_entries;
__u16 bgid;
__u16 pad;
__u64 resv[3];
};
okay so field by field, no cap:
ring_addrβ has to contain the address of the memory you allocated to fit this ring. and listen, that memory must be page aligned, so allocate it properly with something likeposix_memalign(3)or similar. don't be out here raw-doggingmalloc, bestie π- the size of the ring is the product of
ring_entriesand the size ofstruct io_uring_buf ring_entriesβ the desired size of the ring, and it must be a power-of-2 in size. the maximum size allowed is 2^15 (32768).bgidβ the buffer group ID associated with this ring. SQEs that select a buffer have a buffer group associated with them in theirbuf_groupfield, and the associated CQEs will haveIORING_CQE_F_BUFFERset in theirflagsmember, which will also contain the specific ID of the buffer selected. iconic β¨- the rest of the fields are reserved and must be cleared to zero. don't touch them, fr fr.
the flags argument can be set to one of the following values:
IOU_PBUF_RING_INCβ the buffers in this ring can be incrementally consumed. with partial consumption, each completion of a given buffer ID will continue where the previous one left off, or from the start if no completions have been seen yet. when more completions should be expected for a given buffer ID, the CQE will haveIORING_CQE_F_BUF_MOREset in theflagsmember. available since 6.12 π
and a shared buffer ring looks as follows:
struct io_uring_buf_ring {
union {
struct {
__u64 resv1;
__u32 resv2;
__u16 resv3;
__u16 tail;
};
struct io_uring_buf bufs[0];
};
};
where tail is the index at which the application can insert new buffers for consumption by requests π¦ and struct io_uring_buf is the buffer definition:
struct io_uring_buf {
__u64 addr;
__u32 len;
__u16 bid;
__u16 resv;
};
where:
addris the address for the bufferlenis the length of the buffer in bytesbidis the buffer ID that will be returned in the CQE once consumed π
π¨ reserved fields must not be touched. like, at all. hands off. π
applications must use io_uring_buf_ring_init(3) to initialise the buffer ring before use. and you may use io_uring_buf_ring_add(3) and io_uring_buf_ring_advance(3) or io_uring_buf_ring_cq_advance(3) to provide buffers β those will set these fields and update the tail for you. main character helpers only π
available since 5.19. π
π RETURN VALUE π
- on success,
io_uring_register_buf_ring(3)returns 0 β - on failure, it returns
-errnoπ
π NOTES π
unless manual setup is needed, it's recommended to use io_uring_setup_buf_ring(3) instead, because it provides a simpler way to set up a provided buffer ring. lowkey just take the easy path, bestie π«Ά
β SEE ALSO β
io_uring_buf_ring_init(3)io_uring_buf_ring_add(3)io_uring_setup_buf_ring(3)io_uring_buf_ring_advance(3)io_uring_buf_ring_cq_advance(3)
and that's the whole page, bestie!! this one's from liburing-2.2, dated May 18, 2022 π tysm for reading, go register those buffer rings, you're gonna ate πβ¨π§
π¦ where this page comes from
- alpine 3.22: liburing-doc 2.9-r0 Β· LGPL-2.1-or-later OR MIT
- alpine 3.23: liburing-doc 2.12-r0 Β· LGPL-2.1-or-later OR MIT
- alpine 3.24: liburing-doc 2.14-r0 Β· LGPL-2.1-or-later OR MIT
- centos-stream 10: liburing-devel 2.12-1.el10 Β· (GPLv2 with exceptions and LGPLv2+) or MIT
- centos-stream 9: liburing-devel 2.12-1.el9 Β· (GPLv2 with exceptions and LGPLv2+) or MIT
- centos-stream 9: liburing-devel 2.12-1.el9 Β· (GPLv2 with exceptions and LGPLv2+) or MIT
- debian trixie: liburing-dev 2.9-1
- fedora 43: liburing-devel 2.9-2.fc43 Β· (GPL-2.0-only WITH Linux-syscall-note OR MIT) AND (LGPL-2.0-or-later OR MIT)
- fedora 43: liburing-devel 2.9-2.fc43 Β· (GPL-2.0-only WITH Linux-syscall-note OR MIT) AND (LGPL-2.0-or-later OR MIT)
- fedora 44: liburing-devel 2.13-2.fc44 Β· (GPL-2.0-only WITH Linux-syscall-note OR MIT) AND (LGPL-2.0-or-later OR MIT)
- fedora 44: liburing-devel 2.13-2.fc44 Β· (GPL-2.0-only WITH Linux-syscall-note OR MIT) AND (LGPL-2.0-or-later OR MIT)
- nixpkgs unstable: liburing 2.14
- ubuntu questing: liburing-dev 2.11-1
- ubuntu resolute: liburing-dev 2.14-1
- π the page's license: LGPL-2.0-or-later
- Copyright (C) 2022 Jens Axboe <axboe@kernel.dk>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms