io_uring_register_buf_ring(3)

πŸ“¦
version 2.14 Β· 5 versions
, in alpine 3.22, alpine 3.23, alpine 3.24, centos-stream 10, centos-stream 9, debian trixie, fedora 43, fedora 44, nixpkgs unstable, ubuntu questing, ubuntu resolute

πŸ’– 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 like posix_memalign(3) or similar. don't be out here raw-dogging malloc, bestie 😭
  • the size of the ring is the product of ring_entries and the size of struct 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 their buf_group field, and the associated CQEs will have IORING_CQE_F_BUFFER set in their flags member, 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 have IORING_CQE_F_BUF_MORE set in the flags member. 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:

  • addr is the address for the buffer
  • len is the length of the buffer in bytes
  • bid is 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 πŸŽ€


πŸ’œ 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 ⭐


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