The io_uring_register
syscall supports various registration ops to allow a user to register different resources that io_uring
can use.
Specifically, with IORING_REGISTER_PBUF_RING
combined with the IOU_PBUF_RING_MMAP
flag, the kernel allocates pages for an io_buffer_list
and attaches it to the io_ring_ctx
under a given bgid
.
int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
{
struct io_uring_buf_reg reg;
struct io_buffer_list *bl, *free_bl = NULL;
int ret;
if (copy_from_user(®, arg, sizeof(reg)))
return -EFAULT;
/*...*/
if (!(reg.flags & IOU_PBUF_RING_MMAP))
ret = io_pin_pbuf_ring(®, bl);
else
ret = io_alloc_pbuf_ring(®, bl); // <-- IOU_PBUF_RING_MMAP
if (!ret) {
bl->nr_entries = reg.ring_entries;
bl->mask = reg.ring_entries - 1;
io_buffer_add_list(ctx, bl, reg.bgid); // <-- add buffer_list to ctx with bgid
return 0;
}
kfree(free_bl);
return ret;
}
In the io_alloc_pbuf_ring()
function below, the kernel uses __get_free_pages()
to allocate pages for the buffer ring:
static int io_alloc_pbuf_ring(struct io_uring_buf_reg *reg,
struct io_buffer_list *bl)
{
gfp_t gfp = GFP_KERNEL_ACCOUNT | __GFP_ZERO | __GFP_NOWARN | __GFP_COMP;
size_t ring_size;
void *ptr;
ring_size = reg->ring_entries * sizeof(struct io_uring_buf_ring);
ptr = (void *) __get_free_pages(gfp, get_order(ring_size));
if (!ptr)
return -ENOMEM;
bl->buf_ring = ptr;
bl->is_mapped = 1;
bl->is_mmap = 1;
return 0;
}
For more information click here.
When you write a Bash script in Linux, you want it to run correctly every…
Introduction If you’re new to Bash scripting, one of the first skills you’ll need is…
What is Bash Scripting? Bash scripting allows you to save multiple Linux commands in a file and…
When it comes to automating tasks on Linux, Bash scripting is an essential skill for both beginners…
Learn how to create and use Bash functions with this complete tutorial. Includes syntax, arguments,…
Introduction Unlock the full potential of your Linux system with this comprehensive guide to essential…