io_uring_pre...ovide_buffers(3)

πŸ“¦
version 2.15 Β· 2 versions
  • 2.15 Β· alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, centos-stream 10, centos-stream 9, debian trixie, fedora 43, fedora 44, nixpkgs unstable, opensuse-leap 16.0, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking (latest)
  • 2.3 Β· debian bookworm
, in alpine 3.22, alpine 3.23, alpine 3.24, arch rolling, centos-stream 10, centos-stream 9, debian trixie, fedora 43, fedora 44, nixpkgs unstable, opensuse-leap 16.0, ubuntu noble, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ’– io_uring_prep_provide_buffers β€” bestie edition πŸ’–

okay so this is part of the liburing Manual, and we're talking about io_uring_prep_provide_buffers(3). buckle up, it's giving "here's how you hand the kernel a lil pile of buffers" πŸŽ€


✨ NAME ✨

io_uring_prep_provide_buffers β€” prepare a provide buffers request


🌸 SYNOPSIS 🌸

#include <liburing.h>

void io_uring_prep_provide_buffers(struct io_uring_sqe *sqe,
                                   void *addr,
                                   int len,
                                   int nr,
                                   int bgid,
                                   int bid);

πŸ¦‹ DESCRIPTION πŸ¦‹

so bestie, io_uring_prep_provide_buffers(3) gets a request all ready to hand the kernel some buffers. the submission queue entry sqe gets set up to consume nr buffers, each one len in size, starting at addr, tagged with the buffer group ID bgid, and numbered sequentially starting from bid. slay. πŸ’…

this function sets up a request to provide buffers to the io_uring context that can then be used by read or receive operations. it does this by filling in the SQE buf_group field and setting IOSQE_BUFFER_SELECT in the SQE flags member. and here's the tea πŸ«– β€” if buffer selection is used for a request, you should not put a buffer in the address field. instead, you set the group ID to match one that was previously provided to the kernel. then the kernel picks a buffer from that group for the IO operation. when the IO request completes successfully, the CQE flags field will have IORING_CQE_F_BUFFER set, and the selected buffer ID gets indicated by the upper 16-bits of the flags field. iconic behaviour, honestly.

different buffer group IDs can be used by the application so you can have different sizes or types of buffers available at the same time. no cap, very flexible. but listen β€” once a buffer has been consumed for an operation, it is no longer known to io_uring. it must be re-provided if you want it back, or freed by the application if you don't need it anymore. it's giving "use it and lose it" 😭

the buffer IDs are internally tracked from bid and go sequentially ascending from that value. so if 16 buffers are provided and they start with an initial bid of 0, then the buffer IDs will range from 0..15. the application must be aware of this to make sense of the buffer ID passed back in the CQE. main character energy = knowing your own IDs πŸ’…

buffer IDs always range from 0 to 65535, because there are only 16-bits available in the CQE to pass them back. this range is independent of how the buffer group initially got created. attempting to add buffer IDs larger than that, or buffer IDs that will wrap when cast to a 16-bit value, will cause the request to fail with -E2BIG or -EINVAL. so don't try it, bestie, that's a red flag 🚩

not all requests support buffer selection, because it only really makes sense for requests that receive data from the kernel rather than write or provide data. currently, this mode of operation is supported for any file read or socket receive request. attempting to use IOSQE_BUFFER_SELECT with a command that doesn't support it will result in a CQE res error of -EINVAL. also: buffer selection will work with operations that take a struct iovec as its data destination, but only if 1 iovec is provided. one. uno. that's it. πŸ“


🌈 RETURN VALUE 🌈

None


πŸ’œ ERRORS πŸ’œ

these are the errors that get reported in the CQE res field. on success, res will contain 0 or the number of successfully provided buffers. cute!

  • -ENOMEM β€” the kernel was unable to allocate memory for the request. broke behaviour, not the vibe. 😭
  • -EINVAL β€” one of the fields set in the SQE was invalid. check ur fields bestie.
  • -E2BIG β€” the number of buffers provided was too big, or the bid was too big. a max value of USHRT_MAX buffers can be specified.
  • -EFAULT β€” some of the user memory given was invalid for the application.
  • -EOVERFLOW β€” the product of len and nr exceed the valid amount or overflowed, or the sum of addr and the length of buffers overflowed.
  • -EBUSY β€” attempt to update a slot that is already used. occupied. taken. sorry babe. πŸ’€

πŸ‘‘ SEE ALSO πŸ‘‘

io_uring_get_sqe(3), io_uring_submit(3), io_uring_register(2), io_uring_prep_remove_buffers(3)


and that's the whole page, bestie!! this was liburing-2.2, dated March 13, 2022 β€” go forth and provide those buffers, you absolute icon πŸ§šβœ¨πŸ’–

πŸ“¦ where this page comes from